fix(workflows): make pipe-filter detection quote-aware in expressions (#3232)

_evaluate_simple_expression used 'if "|" in expr' / expr.split("|", 1) to detect a filter pipe, so a literal '|' inside a quoted operand (e.g. inputs.x == 'a|b') was mistaken for a filter separator and raised a spurious ValueError ('unknown filter') instead of comparing the string. Use the existing quote/bracket-aware _find_top_level helper (added for the operator-splitting fix) so only a top-level pipe is treated as a filter separator.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ali jawwad
2026-06-30 00:55:45 +05:00
committed by GitHub
parent 3036fe6954
commit 9ece347a77
2 changed files with 28 additions and 5 deletions

View File

@@ -230,11 +230,13 @@ def _evaluate_simple_expression(expr: str, namespace: dict[str, Any]) -> Any:
if expr[:1] in ("'", '"') and expr.find(expr[0], 1) == len(expr) - 1:
return expr[1:-1]
# Handle pipe filters
if "|" in expr:
parts = expr.split("|", 1)
value = _evaluate_simple_expression(parts[0].strip(), namespace)
filter_expr = parts[1].strip()
# Handle pipe filters. Detect the pipe at the top level only, so a literal
# '|' inside a quoted operand (e.g. `inputs.x == 'a|b'`) or nested brackets is
# not mistaken for a filter separator — mirroring the operator parsing below.
pipe_idx = _find_top_level(expr, "|")
if pipe_idx != -1:
value = _evaluate_simple_expression(expr[:pipe_idx].strip(), namespace)
filter_expr = expr[pipe_idx + 1:].strip()
# `from_json` is strict: it takes no arguments and tolerates no
# trailing tokens. Match on the leading filter name and require the