Summary
The flow engine's selector parser treats the entire expression as a single dot-path lookup. When AI agents write natural JavaScript patterns like $.input.maxResults || 10 (default fallback) or $.input.email && $.input.email.length > 0 (conditional check), the engine tries to find an input named maxResults || 10 — which doesn't exist — and fails validation.
Reproduction
The || pattern (default values)
{
"id": "search",
"type": "action",
"action": {
"data": {
"numResults": "$.input.maxResults || 10"
}
}
}
Validation error: Selector "$.input.maxResults || 10" references undefined input "maxResults || 10"
The && pattern (conditional checks)
{
"id": "sendEmail",
"type": "action",
"if": "$.input.recipientEmail && $.input.recipientEmail.length > 0",
"action": { ... }
}
Validation error: Selector "$.input.recipientEmail && $.input.recipientEmail.length > 0" references undefined input "recipientEmail && $"
Why AI agents write this
Both patterns are idiomatic JavaScript. When an AI agent designs a workflow with optional inputs, $.input.x || defaultValue is the natural way to express "use this input if provided, otherwise fall back to a default." Similarly, $.input.x && $.input.x.length > 0 is the natural null-safe check before using an optional string.
How often this happens
We built 65 n8n-replicated flows in a single session. This issue appeared in:
- 2 flows with
&& in if conditions (go-to-marketing, research-agent)
- 2 flows with
|| default fallbacks (google-maps-scraper, scrape-leads-google-maps)
That's 4 out of 65 (6%) — frequent enough that any batch of AI-generated flows will hit it.
Current workarounds
For || defaults: Declare the default in the input definition and reference $.input.x directly:
{
"inputs": {
"maxResults": { "type": "number", "default": 10 }
},
"steps": [{
"action": { "data": { "numResults": "$.input.maxResults" } }
}]
}
For && conditionals: Simplify to a truthy check:
{
"if": "$.input.recipientEmail"
}
Suggested fix
Either:
Option A: Expand the selector parser to support || and && as JavaScript expressions (evaluate them at runtime instead of treating the whole string as a dot-path).
Option B: Document the limitation in the skill's selector syntax reference and add a validation error message that suggests the workaround:
Selector "$.input.maxResults || 10" contains unsupported operator "||".
Use the "default" field on the input definition instead, or use a "code" step for complex expressions.
Option B is lower effort and would prevent AI agents from hitting a confusing error.
Related
This is the same class of issue as:
- cli#6 (default values not resolved — now fixed in 1.14.1)
- cli#12 (parseJson:true fails — skill teaches a pattern that doesn't work)
All three are cases where the flow engine's behavior surprises AI agents that write natural JavaScript patterns.
Summary
The flow engine's selector parser treats the entire expression as a single dot-path lookup. When AI agents write natural JavaScript patterns like
$.input.maxResults || 10(default fallback) or$.input.email && $.input.email.length > 0(conditional check), the engine tries to find an input namedmaxResults || 10— which doesn't exist — and fails validation.Reproduction
The
||pattern (default values){ "id": "search", "type": "action", "action": { "data": { "numResults": "$.input.maxResults || 10" } } }Validation error:
Selector "$.input.maxResults || 10" references undefined input "maxResults || 10"The
&&pattern (conditional checks){ "id": "sendEmail", "type": "action", "if": "$.input.recipientEmail && $.input.recipientEmail.length > 0", "action": { ... } }Validation error:
Selector "$.input.recipientEmail && $.input.recipientEmail.length > 0" references undefined input "recipientEmail && $"Why AI agents write this
Both patterns are idiomatic JavaScript. When an AI agent designs a workflow with optional inputs,
$.input.x || defaultValueis the natural way to express "use this input if provided, otherwise fall back to a default." Similarly,$.input.x && $.input.x.length > 0is the natural null-safe check before using an optional string.How often this happens
We built 65 n8n-replicated flows in a single session. This issue appeared in:
&&inifconditions (go-to-marketing, research-agent)||default fallbacks (google-maps-scraper, scrape-leads-google-maps)That's 4 out of 65 (6%) — frequent enough that any batch of AI-generated flows will hit it.
Current workarounds
For
||defaults: Declare the default in the input definition and reference$.input.xdirectly:{ "inputs": { "maxResults": { "type": "number", "default": 10 } }, "steps": [{ "action": { "data": { "numResults": "$.input.maxResults" } } }] }For
&&conditionals: Simplify to a truthy check:{ "if": "$.input.recipientEmail" }Suggested fix
Either:
Option A: Expand the selector parser to support
||and&&as JavaScript expressions (evaluate them at runtime instead of treating the whole string as a dot-path).Option B: Document the limitation in the skill's selector syntax reference and add a validation error message that suggests the workaround:
Option B is lower effort and would prevent AI agents from hitting a confusing error.
Related
This is the same class of issue as:
All three are cases where the flow engine's behavior surprises AI agents that write natural JavaScript patterns.