diff --git a/workflows/tests/test_workflow_execution.py b/workflows/tests/test_workflow_execution.py index 472c645..f8eef84 100644 --- a/workflows/tests/test_workflow_execution.py +++ b/workflows/tests/test_workflow_execution.py @@ -158,6 +158,23 @@ def test_semantic_strategies_format(self): assert 'priority' in strategy, "Strategy missing 'priority'" assert 'metadata' in strategy, "Strategy missing 'metadata'" + # Test 11: _resolve_placeholders returns original string for positional format specifiers + def test_resolve_placeholders_positional_format_specifier(self): + """Positional placeholders like {0} must not crash; original string is returned unchanged.""" + def _resolve_placeholders(data, context): + if isinstance(data, str): + try: + if '{' in data and '}' in data: + return data.format(**context) + return data + except (KeyError, IndexError, ValueError): + return data + return data + + url = "https://example.com/item/{0}/details" + result = _resolve_placeholders(url, {}) + assert result == url, f"Expected original URL, got: {result}" + # Validate semantic-only (no CSS/xpath) strategy_types = [s['type'] for s in strategies] assert 'css' not in strategy_types, 'Should not have CSS strategies' diff --git a/workflows/workflow_use/workflow/service.py b/workflows/workflow_use/workflow/service.py index 1a6c325..b4656a2 100644 --- a/workflows/workflow_use/workflow/service.py +++ b/workflows/workflow_use/workflow/service.py @@ -517,9 +517,11 @@ def _resolve_placeholders(self, data: Any) -> Any: formatted_data = data.format(**self.context) return formatted_data return data # No placeholders, return as is - except KeyError: - # A key in the placeholder was not found in the context. - # Return the original string as per previous behavior. + except (KeyError, IndexError, ValueError): + # A key in the placeholder was not found in the context (KeyError), + # or a positional format specifier like {0} was present (IndexError), + # or the format string was otherwise invalid (ValueError). + # Return the original string unchanged. return data # TODO: This next things are not really supported atm, we'll need to to do it in the future.