
Step by Step Guide to solve n8n Function Node Reference Error
Who this is for: n8n developers and workflow engineers who encounter ReferenceError messages in Function nodes and need a concise, production‑ready resolution path.
Quick Diagnosis
ReferenceError in an n8n Function node means the script is trying to read a variable that hasn’t been declared in the current scope. We cover this in detail in the n8n Node Specific Errors Guide.
Quick fix:
- Open the Function node → Code tab.
- Declare every variable with
let,const, orvar. - Pull data from other nodes via
items[0].json.<field>orawait this.getNode('NodeName').run(). - Save and re‑run the workflow.
1. What Triggers a ReferenceError in a Function Node?
If you encounter any n8n set node type mismatch resolve them before continuing with the setup.
| Trigger | Why it Happens | Typical Symptom |
|---|---|---|
Missing declaration (let/const/var) |
JavaScript cannot find the identifier in the current lexical environment. | ReferenceError: myVar is not defined |
| Typo in variable name | The spelled‑out identifier differs from the declared one. | Same error, but the variable does exist elsewhere. |
| Scope mismatch (global vs. node) | n8n isolates each Function node; variables defined outside the node aren’t visible inside. | ReferenceError: externalVar is not defined |
| Async/await misuse | await used outside an async function or before a promise resolves. |
ReferenceError: await is not defined |
| Dynamic property access with undefined key | The computed key is undefined, leading to a missing reference. |
ReferenceError: dynamicKey is not defined |
2. Step‑by‑Step Debugging Workflow
If you encounter any n8n merge node type mismatch resolve them before continuing with the setup.
Purpose: Walk through the exact actions you should take when a ReferenceError appears.
- Open the Function node in “Code” view – this is where the error originates.
- Locate the error line – the UI highlights the line number in the console output (e.g.,
ReferenceError: foo is not defined at line 12). - Verify declaration – search the file (
Ctrl+F) forlet foo,const foo, orvar foo.
• If missing: add the appropriate declaration.
• If present: check the spelling and case sensitivity. - Check variable scope –
• Inside the node: variables must be declared within the same Function node or passed viaitems.
• From other nodes: useitems[0].json.<field>orawait this.getNode('NodeName').run()to fetch data. - Log the runtime context – prepend a small log to see what’s actually available.
// Quick debug: show what variables exist this.logger.debug({ foo, items }); - Execute the workflow in “Execute Workflow” mode – the built‑in debugger shows the exact stack trace.
- Apply the fix → Save → Re‑run.
EEFA Note: In production, replace
console.logwiththis.logger.debug()to avoid log noise and accidental exposure of sensitive data.
3. Real‑World Example – Reproducing & Fixing a ReferenceError
3.1 Problematic script (throws ReferenceError)
The script tries to use inputData without ever defining it.
// Function node code (original)
const result = processData(inputData);
return [{ json: { result } }];
function processData(data) {
// `inputData` is never declared – typo!
return data.map(item => item.value * multiplier);
}
3.2 Fix #1 – Declare the missing variable correctly
Declare inputData from the incoming items array and ensure multiplier is defined.
// Fixed version – explicit inputData
const inputData = items.map(i => i.json); // Pull data from previous node
const result = processData(inputData);
return [{ json: { result } }];
function processData(data) {
const multiplier = 2;
return data.map(item => item.value * multiplier);
}
3.3 Fix #2 – Streamlined version using items directly
Eliminate the intermediate variable and keep the function pure.
// Streamlined version – no extra variable
function processData(data) {
const multiplier = 2;
return data.map(item => item.value * multiplier);
}
return [{ json: { result: processData(items.map(i => i.json)) } }];
Both fixes remove the ReferenceError.
EEFA Tip: The second pattern reduces memory churn in high‑throughput workflows by avoiding unnecessary intermediate arrays.
4. Checklist – Prevent ReferenceErrors in Function Nodes
If you encounter any
n8n function node syntax error
resolve them before continuing.
- All variables declared with
let,const, orvar. - Naming consistency – identical spelling & case throughout the script.
- Scope awareness – only use variables defined inside the node or passed via
items. - Async functions are marked
asyncandawaitis only used on promises. - Dynamic keys have a fallback (
const key = dynamicKey || 'default';). - No stray
evalornew Function– they bypass static analysis and raise hidden reference issues. - Remove debugging
console.logbefore deploying to production.
5. Production‑Grade EEFA Guidance
| Concern | Why it Matters | Recommended Fix |
|---|---|---|
| Hidden global leakage | Declaring a variable without let/const creates an implicit global, which can be overwritten by another node’s script. |
Always use let/const. Add "use strict"; at the top of the script. |
| Version drift | n8n upgrades may change the sandbox environment (e.g., Node.js version). | Pin the Node.js version in your self‑hosted deployment or test against the exact n8n Docker image you run. |
| Error masking | A try { … } catch (e) {} that only logs e.message hides the stack trace, making future debugging harder. |
Log the full error: this.logger.error(e.stack); and re‑throw if the workflow should fail. |
| Sensitive data exposure | Logging full items can leak API keys or PII. |
Redact before logging: const safe = items.map(i => ({ ...i, json: { ...i.json, apiKey: '[REDACTED]' } })); |
Conclusion
ReferenceErrors in n8n Function nodes stem from undeclared or mis‑scoped identifiers. By declaring every variable, respecting node isolation, and using the built‑in items array for data exchange, you eliminate these runtime failures. Adopt strict mode, keep logging production‑ready, and verify compatibility with your n8n version to ensure robust, maintainable workflows in real‑world deployments.



