n8n Error Reference
Cannot read properties of undefined
This JavaScript TypeError fires when an n8n node tries to access a property on a value that doesn't exist at that path. The property name in parentheses is what n8n was looking for when it hit undefined.
Quick Diagnosis
Open the failed node in the execution log → click the Input tab → check whether the field referenced in the error exists in the data. If the input is empty or the field is missing, the problem is in the node before this one.
Error variants
The property in parentheses is what n8n was trying to read when it hit undefined:
What this error means
JavaScript uses undefined to represent a value that doesn't exist at a given path. When n8n evaluates an expression like {{ $json.items }} and there's nothing at that path in the incoming data, the result is undefined. Any attempt to then read a property from undefined — .map(), .content, .name, .execute — throws this error. The cause is usually one of two things: the upstream node didn't return the expected data, or the expression on the failing node references the wrong path. Both produce the same error; the difference is whether the data is missing entirely or just at a different nesting level than expected.
Common causes
Empty output from an upstream node
A Filter, If, database query, or HTTP Request node returned zero items. The downstream node receives no input, so $input.item and $json are both undefined. Check the Output tab of the node before the one that failed — did it return any items at all?
Expression references the wrong nesting level
The field exists, but one level deeper than the expression expects. $json.items fails when the actual path is $json.data.items. $json.content fails when it's $json.message.content. Even a single extra or missing level produces undefined on every execution.
API response structure changed
An external API updated its response envelope. A field that was at response.name moved to response.data.name, or was renamed entirely. The workflow succeeded before the API change and now fails on every run without any change to the workflow itself.
Code node returning the wrong shape
n8n Code nodes must return an array of objects with a json key: [{ json: { ... } }]. If the return value is a plain object, a raw array, or undefined, downstream nodes receive malformed input and property access on that input throws this error.
Conditional branch produced no output
A Switch or If node routed execution down a path that produced no items. A subsequent node still tries to read $input.item, which is undefined because nothing was passed along that branch.
Field present on some items but not all
The workflow succeeds on most executions because the field usually exists. One record from the source — a database NULL, an API response omitting an optional field — causes undefined at runtime. The error is intermittent and only surfaces for those specific records.
How to diagnose it
- 1
Open the failed execution, click the red failed node, and select the Input tab. Check whether any items are present and whether the field referenced in the error appears in the data.
- 2
If the input is empty (no items shown), the failing node is not the cause — the problem is in the node before it. Open that node and check its Output tab.
- 3
If items are present but the field is missing, compare the actual key names in the Input tab against the expression or code that references them. Expand every nested level and look for the field at each depth.
- 4
For expression errors: open the expression editor on the field that failed. n8n resolves the expression live — if it shows undefined, the path is wrong.
- 5
For Code node errors: add console.log(JSON.stringify($input.all())) at the top of the code and re-run. The output appears in the execution log and shows the actual shape of the data the node received.
- 6
If the error is intermittent: add an If node before the failing node to check that the required field exists ({{ $json.fieldName !== undefined }}) and route the missing-field case to a separate branch or a Stop And Error node.
n8n-specific scenarios
OpenAI node → reading 'content'
n8n's built-in OpenAI Chat Model node puts the reply at $json.message.content, not $json.content. If you're using an HTTP Request node to call OpenAI's API directly, the path is $json.choices[0].message.content. Accessing $json.content on either returns undefined. Open the Output tab of the OpenAI node to see the exact structure before writing any downstream expression.
HTTP Request → expression one nesting level off
The API returns { "data": { "users": [...] } }. An expression using $json.users fails because users is nested under data. The correct path is $json.data.users. Use the Input tab on the downstream node — not the Output tab of the HTTP Request node — to expand the JSON and verify the path.
Execute Workflow node → reading 'execute'
The Execute Workflow node stores a reference to a workflow by ID. If that workflow was deleted, if the instance was migrated and IDs changed, or if the workflow was moved to a different project, n8n cannot locate it. The internal .execute() call runs on undefined and throws. Open the Execute Workflow node and verify the referenced workflow ID still exists.
Database query → NULL field in one row
A Postgres or MySQL node returns rows where one column is NULL for certain records. n8n converts SQL NULL to null in JSON. If the downstream expression or Code node expects a string and tries to access a property on null, it throws the same error. Add an If node to filter rows where the field is null, or handle null explicitly in a Code node before passing data downstream.
Code node → reading 'map' on undefined items
A Code node contains items.map(item => ...) but items is undefined when no data is passed in — for example, when a Filter node upstream returns zero matches. Add a guard before the .map() call: if (!Array.isArray(items) || items.length === 0) return []; This returns an empty result set instead of throwing, and a downstream If node can handle the empty case explicitly.
Split In Batches with a short or empty final batch
The Split In Batches node can produce an undersized or empty final batch depending on total item count and batch size. A downstream Code node that calls $input.all().map(item => item.json.fieldName) throws if any item in the batch is missing fieldName. Check every field access inside batch-processing Code nodes — don't assume all items in a batch have the same shape.
Paste your full error message and the failed node's output into Debugalo to get a structured breakdown: the exact failed step, root cause, and concrete fix steps.
Analyze this error →FAQ
Why does this error only happen on some executions?
The data varies between runs. When every upstream record includes the expected field, the workflow succeeds. When one record has a missing field, a NULL, or when an API returns an empty result set, the undefined reference surfaces. The fix is an If node that checks the field exists before passing data to the node that depends on it.
What's the difference between undefined and null in this context?
Null means the field exists in the JSON but was explicitly set to null. Undefined means the field does not exist at that path at all. Both cause this error if you try to read a property from them. The fix is the same in both cases: check that the value exists and is not null before accessing any property on it.
The Input tab shows data, but the error still fires. Why?
The expression is referencing a path that's one level off from what's visible in the Input tab. The data exists, but at a different nesting depth than the expression expects. Expand every nested object in the Input tab and count the levels. Even a single extra or missing level like .data. or .response. produces undefined.
Can I make the node continue instead of stopping the whole execution?
Yes. In the node's settings panel, expand Error Handling and enable Continue On Error. The execution logs the error and moves on instead of stopping. Use it only when skipping a bad item is intentional — it doesn't fix the expression or the data.
How do I fix reading 'map' in a Code node?
Add a guard before the .map() call: if (!Array.isArray(items) || items.length === 0) return []; Place it as the first line of the Code node. This returns an empty result set instead of throwing when the input is undefined or empty. A downstream If node can then check whether the output contains items and route accordingly.