n8n-io/n8n · error · ExpressionError

expected two arguments (Object, string) for this function

Error message

expected two arguments (Object, string) for this function

What it means

Argument-shape validation at the entry of the in-isolate jmesPath wrapper: it requires exactly (object, string) — the data to query must be an object and the JMESPath query a string. Any other combination (number data, missing query, object query) is rejected before jmespath.search runs.

Solutions

  1. Pass the data as the first argument and the JMESPath query string as the second
  2. Wrap non-object data (array is fine; scalars are not) in an object before querying
  3. Check for a missing or malformed second argument in theJmesPath()/jmespath() call
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/@n8n/expression-runtime/src/runtime/jmespath.ts:68 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/7213ce0f2afe70e9. Report an issue: GitHub.

Appendix: source

Thrown at packages/@n8n/expression-runtime/src/runtime/jmespath.ts:68

 *   - Throws `ExpressionError` (same name) when args are wrong.
 *   - Rejects queries that contain unsafe property tokens.
 *   - Does NOT spread `data` before querying. Host-side, the top-level
 *     spread exists to strip proxies off the data before handing it to
 *     jmespath; in-isolate that is a no-op (nested values stay lazy
 *     proxies either way, and the isolate boundary already prevents
 *     host-object leakage), while spreading a lazy proxy (e.g. `$json`)
 *     would cost one synchronous host roundtrip per top-level key
 *     before the query even runs.
 *
 * Note on lazy proxies: when `data` is a lazy proxy (e.g. `$json`), each
 * property access during `jmespath.search` triggers a synchronous host
 * roundtrip via `getValueAtPath`. Functional but slow for deep traversals.
 * Performance optimisation (e.g. bulk pre-fetch of the queried subtree) is
 * a follow-up.
 */
export function jmesPath(data: unknown, query: string): unknown {
	if (typeof data !== 'object' || typeof query !== 'string') {
		throw new ExpressionError('expected two arguments (Object, string) for this function');
	}

	// jmespath decodes escape sequences inside quoted identifiers, so the
	// token check must run against an unescaped query. Reject any backslash
	// up front to keep the property-name match meaningful.
	if (query.includes('\\') || unsafeJmespathPropertyPattern.test(query)) {
		throw new ExpressionError(
			'Cannot access this property in a jmespath query due to security concerns',
		);
	}

	return jmespath.search(data as never, query);
}

View on GitHub (pinned to 5ac6606e81)