n8n-io/n8n · error · InterpreterError

Cannot access property on ${obj}

Error message

Cannot access property on ${obj}

What it means

When evaluating a member expression (`obj.prop`), the interpreter first evaluates the object at interpreter.ts:325. If it resolves to `null` or `undefined`, the interpreter throws `InterpreterError` at line 328 rather than letting the property access produce a confusing `TypeError`. This gives a clear source-located error message.

Source

Thrown at packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts:328

	/**
	 * Visit a member expression (for property access, not method calls).
	 */
	private visitMemberExpression(node: ESTree.MemberExpression): unknown {
		validateMemberExpression(node, this.sourceCode);

		// Handle Super type (super keyword) - not supported in SDK code
		if (node.object.type === 'Super') {
			throw new UnsupportedNodeError(
				'super keyword is not supported in SDK code',
				node.object.loc ?? undefined,
				this.sourceCode,
			);
		}

		const obj = this.evaluate(node.object);

		if (obj === null || obj === undefined) {
			throw new InterpreterError(
				`Cannot access property on ${obj}`,
				node.loc ?? undefined,
				this.sourceCode,
			);
		}

		// Get property name
		let propName: string | number;
		if (node.property.type === 'Identifier' && !node.computed) {
			propName = node.property.name;
		} else if (node.property.type === 'Literal') {
			propName = node.property.value as string | number;
		} else {
			throw new UnsupportedNodeError(
				'Dynamic property access',
				node.property.loc ?? undefined,
				this.sourceCode,
			);

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Guard with a conditional: `x ? x.field : defaultValue`
  2. Ensure the SDK function returns a value before property access
  3. Use nullish coalescing to provide a safe default: `(x ?? {}).field`

Example fix

// before
const name = maybeNode.name; // maybeNode could be undefined

// after
const name = maybeNode ? maybeNode.name : 'default';
Defensive patterns

Strategy: type-guard

Validate before calling

// Pre-check: trace member accesses on potentially-null values
// Use conditional expressions in SDK code (supported):
// const val = obj ? obj.prop : defaultValue;

Type guard

// In SDK code, guard with ternary (ConditionalExpression IS supported):
// const val = (obj != null) ? obj.prop : undefined;

// In the CALLER (TypeScript), guard interpreter inputs:
function isNotNullish<T>(value: T | null | undefined): value is T {
  return value !== null && value !== undefined;
}

Try / catch

import { InterpreterError } from '@n8n/workflow-sdk/ast-interpreter/errors';

try {
  interpretSDKCode(sdkCode, sdkFunctions);
} catch (e) {
  if (e instanceof InterpreterError && e.message.includes('Cannot access property on')) {
    // suggest adding a null check: obj ? obj.prop : fallback
  }
  throw e;
}

Prevention

When it happens

Trigger: Writing `null.name`, `undefined.prop`, or accessing a property on a variable that resolved to null/undefined: `const x = maybeNothing(); x.field`. The check `obj === null || obj === undefined` at line 327 fires before property access.

Common situations: SDK function returns null/undefined unexpectedly; accessing properties of optional fields; chained access where an intermediate value is null; referencing `$json` fields that don't exist.

Related errors


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