{"record":{"id":"9ecfebd161f23cce","repo":"n8n-io/n8n","slug":"cannot-access-property-on-obj","errorCode":null,"errorMessage":"Cannot access property on ${obj}","messagePattern":"Cannot access property on (.+?)","errorType":"exception","errorClass":"InterpreterError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts","lineNumber":328,"sourceCode":"\t/**\n\t * Visit a member expression (for property access, not method calls).\n\t */\n\tprivate visitMemberExpression(node: ESTree.MemberExpression): unknown {\n\t\tvalidateMemberExpression(node, this.sourceCode);\n\n\t\t// Handle Super type (super keyword) - not supported in SDK code\n\t\tif (node.object.type === 'Super') {\n\t\t\tthrow new UnsupportedNodeError(\n\t\t\t\t'super keyword is not supported in SDK code',\n\t\t\t\tnode.object.loc ?? undefined,\n\t\t\t\tthis.sourceCode,\n\t\t\t);\n\t\t}\n\n\t\tconst obj = this.evaluate(node.object);\n\n\t\tif (obj === null || obj === undefined) {\n\t\t\tthrow new InterpreterError(\n\t\t\t\t`Cannot access property on ${obj}`,\n\t\t\t\tnode.loc ?? undefined,\n\t\t\t\tthis.sourceCode,\n\t\t\t);\n\t\t}\n\n\t\t// Get property name\n\t\tlet propName: string | number;\n\t\tif (node.property.type === 'Identifier' && !node.computed) {\n\t\t\tpropName = node.property.name;\n\t\t} else if (node.property.type === 'Literal') {\n\t\t\tpropName = node.property.value as string | number;\n\t\t} else {\n\t\t\tthrow new UnsupportedNodeError(\n\t\t\t\t'Dynamic property access',\n\t\t\t\tnode.property.loc ?? undefined,\n\t\t\t\tthis.sourceCode,\n\t\t\t);","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts#L310-L346","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Guard with a conditional: `x ? x.field : defaultValue`","Ensure the SDK function returns a value before property access","Use nullish coalescing to provide a safe default: `(x ?? {}).field`"],"exampleFix":"// before\nconst name = maybeNode.name; // maybeNode could be undefined\n\n// after\nconst name = maybeNode ? maybeNode.name : 'default';","handlingStrategy":"type-guard","validationCode":"// Pre-check: trace member accesses on potentially-null values\n// Use conditional expressions in SDK code (supported):\n// const val = obj ? obj.prop : defaultValue;","typeGuard":"// In SDK code, guard with ternary (ConditionalExpression IS supported):\n// const val = (obj != null) ? obj.prop : undefined;\n\n// In the CALLER (TypeScript), guard interpreter inputs:\nfunction isNotNullish<T>(value: T | null | undefined): value is T {\n  return value !== null && value !== undefined;\n}","tryCatchPattern":"import { InterpreterError } from '@n8n/workflow-sdk/ast-interpreter/errors';\n\ntry {\n  interpretSDKCode(sdkCode, sdkFunctions);\n} catch (e) {\n  if (e instanceof InterpreterError && e.message.includes('Cannot access property on')) {\n    // suggest adding a null check: obj ? obj.prop : fallback\n  }\n  throw e;\n}","preventionTips":["Guard property access with ternaries: `obj ? obj.field : fallback`","Use nullish coalescing: `(obj ?? {}).field`","Verify SDK functions return non-null before chaining property access"],"tags":["sdk-interpreter","null-access","runtime","property-access"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}