Skip to content

Conversation

@majiayu000
Copy link

Summary

  • Fixes expression parser incorrectly identifying }} inside quoted strings as expression closing marker
  • Adds string context tracking (single quotes, double quotes, backticks)
  • Properly handles escape sequences inside strings

Test plan

  • Added comprehensive unit tests for splitExpression and joinExpression
  • Tests cover JMESPath expressions with nested braces
  • Tests cover all quote types (single, double, backtick)
  • Tests cover escaped quotes inside strings
  • All existing expression tests pass
  • TypeScript checks pass

Example

Before this fix, the expression:

{{ $jmespath($json, '{reviewers: values[*].{uuid: user.uuid}}') }}

Would fail with "invalid syntax" because }} inside the JMESPath string was interpreted as the expression end marker.

After this fix, the expression is correctly parsed and executed.

Fixes #22264

When parsing expressions like `{{ $jmespath($json, '{a: b}') }}`,
the parser would incorrectly identify `}}` inside quoted strings as
the expression closing marker.

This fix adds string context tracking to the expression parser:
- Single quotes, double quotes, and backticks are now tracked
- `}}` inside quoted strings is skipped when searching for the
  expression end marker
- Escape sequences inside strings are handled correctly

Fixes n8n-io#22264

Signed-off-by: majiayu000 <majiayu000@gmail.com>
Signed-off-by: majiayu000 <1835304752@qq.com>
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/workflow/src/extensions/expression-parser.ts">

<violation number="1" location="packages/workflow/src/extensions/expression-parser.ts:38">
P1: Escape handling doesn&#39;t account for consecutive backslashes (`\\`). When `\\` appears before a quote, the quote should close the string (since the first `\` escapes the second `\`, not the quote). The current logic incorrectly skips the quote because it only checks if `prevChar === &#39;\\&#39;` without tracking whether that backslash was itself escaped.

Consider tracking escape state instead of just checking the previous character:</violation>
</file>

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

const prevChar = i > 0 ? text[i - 1] : '';

// Skip escaped characters
if (prevChar === '\\') {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Dec 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Escape handling doesn't account for consecutive backslashes (\\). When \\ appears before a quote, the quote should close the string (since the first \ escapes the second \, not the quote). The current logic incorrectly skips the quote because it only checks if prevChar === '\\' without tracking whether that backslash was itself escaped.

Consider tracking escape state instead of just checking the previous character:

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/workflow/src/extensions/expression-parser.ts, line 38:

<comment>Escape handling doesn&#39;t account for consecutive backslashes (`\\`). When `\\` appears before a quote, the quote should close the string (since the first `\` escapes the second `\`, not the quote). The current logic incorrectly skips the quote because it only checks if `prevChar === &#39;\\&#39;` without tracking whether that backslash was itself escaped.

Consider tracking escape state instead of just checking the previous character:</comment>

<file context>
@@ -21,6 +21,36 @@ export const escapeCode = (text: string): string =&gt; {
+		const prevChar = i &gt; 0 ? text[i - 1] : &#39;&#39;;
+
+		// Skip escaped characters
+		if (prevChar === &#39;\\&#39;) {
+			continue;
+		}
</file context>
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Node fails on complex JMESPath projection

1 participant