<p><img class="alignnone size-full wp-image-4374" src="https://flowgenius.in/wp-content/uploads/2026/01/Child-6-Cluster-9.png" alt="" /></p>
<p style="text-align: center;">Step by Step Guide to solve n8n Function Node Reference Error</p>
<p> </p>
<hr />
<p> </p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Who this is for: </strong>n8n developers and workflow engineers who encounter <code>ReferenceError</code> messages in Function nodes and need a concise, production‑ready resolution path.</p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">Quick Diagnosis</h2>
<blockquote style="margin: 0 0 2em 0; padding-left: 1em; border-left: 4px solid #ddd;">
<p style="margin: 0; line-height: 1.9;"><strong>ReferenceError in an n8n Function node</strong> means the script is trying to read a variable that hasn’t been declared in the current scope. <strong>We cover this in detail in the</strong> <a href="https://flowgenius.in/n8n-node-errors-troubleshooting/">n8n Node Specific Errors Guide.</a></p>
</blockquote>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Quick fix:</strong></p>
<ol style="margin-bottom: 2em; line-height: 1.9;">
<li>Open the Function node → <strong>Code</strong> tab.</li>
<li>Declare every variable with <code>let</code>, <code>const</code>, or <code>var</code>.</li>
<li>Pull data from other nodes via <code>items[0].json.<field></code> or <code>await this.getNode('NodeName').run()</code>.</li>
<li>Save and re‑run the workflow.</li>
</ol>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">1. What Triggers a ReferenceError in a Function Node?</h2>
<p><strong>If you encounter any</strong> <a href="/n8n-set-node-type-mismatch">n8n set node type mismatch</a><strong> resolve them before continuing with the setup.</strong></p>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="border: 1px solid #ddd; padding: 13px; text-align: left;">Trigger</th>
<th style="border: 1px solid #ddd; padding: 13px; text-align: left;">Why it Happens</th>
<th style="border: 1px solid #ddd; padding: 13px; text-align: left;">Typical Symptom</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Missing declaration (<code>let/const/var</code>)</td>
<td style="border: 1px solid #ddd; padding: 13px;">JavaScript cannot find the identifier in the current lexical environment.</td>
<td style="border: 1px solid #ddd; padding: 13px;"><code>ReferenceError: myVar is not defined</code></td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Typo in variable name</td>
<td style="border: 1px solid #ddd; padding: 13px;">The spelled‑out identifier differs from the declared one.</td>
<td style="border: 1px solid #ddd; padding: 13px;">Same error, but the variable <em>does</em> exist elsewhere.</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Scope mismatch (global vs. node)</td>
<td style="border: 1px solid #ddd; padding: 13px;">n8n isolates each Function node; variables defined outside the node aren’t visible inside.</td>
<td style="border: 1px solid #ddd; padding: 13px;"><code>ReferenceError: externalVar is not defined</code></td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Async/await misuse</td>
<td style="border: 1px solid #ddd; padding: 13px;"><code>await</code> used outside an <code>async</code> function or before a promise resolves.</td>
<td style="border: 1px solid #ddd; padding: 13px;"><code>ReferenceError: await is not defined</code></td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Dynamic property access with undefined key</td>
<td style="border: 1px solid #ddd; padding: 13px;">The computed key is <code>undefined</code>, leading to a missing reference.</td>
<td style="border: 1px solid #ddd; padding: 13px;"><code>ReferenceError: dynamicKey is not defined</code></td>
</tr>
</tbody>
</table>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">2. Step‑by‑Step Debugging Workflow</h2>
<p><strong>If you encounter any</strong> <a href="/n8n-merge-node-type-mismatch">n8n merge node type mismatch</a><strong> resolve them before continuing with the setup.</strong></p>
<p style="margin-bottom: 2em; line-height: 1.9;"><em>Purpose:</em> Walk through the exact actions you should take when a ReferenceError appears.</p>
<ol style="margin-bottom: 2em; line-height: 1.9;">
<li><strong>Open the Function node in “Code” view</strong> – this is where the error originates.</li>
<li><strong>Locate the error line</strong> – the UI highlights the line number in the console output (e.g., <code>ReferenceError: foo is not defined at line 12</code>).</li>
<li><strong>Verify declaration</strong> – search the file (<code>Ctrl+F</code>) for <code>let foo</code>, <code>const foo</code>, or <code>var foo</code>.<br />
• <em>If missing</em>: add the appropriate declaration.<br />
• <em>If present</em>: check the spelling and case sensitivity.</li>
<li><strong>Check variable scope</strong> –<br />
• <strong>Inside the node</strong>: variables must be declared within the same Function node or passed via <code>items</code>.<br />
• <strong>From other nodes</strong>: use <code>items[0].json.<field></code> or <code>await this.getNode('NodeName').run()</code> to fetch data.</li>
<li><strong>Log the runtime context</strong> – prepend a small log to see what’s actually available.
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; line-height: 1.9; overflow: auto;">// Quick debug: show what variables exist
this.logger.debug({ foo, items });
</pre>
</li>
<li><strong>Execute the workflow in “Execute Workflow” mode</strong> – the built‑in debugger shows the exact stack trace.</li>
<li><strong>Apply the fix → Save → Re‑run</strong>.<br />
<blockquote style="margin: 0 0 2em 0; padding-left: 1em; border-left: 4px solid #ddd;">
<p style="margin: 0; line-height: 1.9;"><strong>EEFA Note:</strong> In production, replace <code>console.log</code> with <code>this.logger.debug()</code> to avoid log noise and accidental exposure of sensitive data.</p>
</blockquote>
</li>
</ol>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">3. Real‑World Example – Reproducing & Fixing a ReferenceError</h2>
<h3 style="margin-bottom: 45px; line-height: 1.3;">3.1 Problematic script (throws ReferenceError)</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">The script tries to use <code>inputData</code> without ever defining it.</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; line-height: 1.9; overflow: auto;">// 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);
}
</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">3.2 Fix #1 – Declare the missing variable correctly</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">Declare <code>inputData</code> from the incoming <code>items</code> array and ensure <code>multiplier</code> is defined.</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; line-height: 1.9; overflow: auto;">// 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);
}
</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">3.3 Fix #2 – Streamlined version using <code>items</code> directly</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">Eliminate the intermediate variable and keep the function pure.</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; line-height: 1.9; overflow: auto;">// 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)) } }];
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Both fixes remove the <code>ReferenceError</code>.</p>
<blockquote style="margin: 0 0 2em 0; padding-left: 1em; border-left: 4px solid #ddd;">
<p style="margin: 0; line-height: 1.9;"><strong>EEFA Tip:</strong> The second pattern reduces memory churn in high‑throughput workflows by avoiding unnecessary intermediate arrays.</p>
</blockquote>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">4. Checklist – Prevent ReferenceErrors in Function Nodes</h2>
<p><strong>If you encounter any</strong><br />
<a href="/n8n-function-node-syntax-error">n8n function node syntax error</a><br />
<strong> resolve them before continuing.</strong></p>
<ul style="margin-bottom: 2em; line-height: 1.9;">
<li>All variables declared with <code>let</code>, <code>const</code>, or <code>var</code>.</li>
<li>Naming consistency – identical spelling & case throughout the script.</li>
<li>Scope awareness – only use variables defined inside the node or passed via <code>items</code>.</li>
<li>Async functions are marked <code>async</code> and <code>await</code> is only used on promises.</li>
<li>Dynamic keys have a fallback (<code>const key = dynamicKey || 'default';</code>).</li>
<li>No stray <code>eval</code> or <code>new Function</code> – they bypass static analysis and raise hidden reference issues.</li>
<li>Remove debugging <code>console.log</code> before deploying to production.</li>
</ul>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">5. Production‑Grade EEFA Guidance</h2>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="border: 1px solid #ddd; padding: 13px; text-align: left;">Concern</th>
<th style="border: 1px solid #ddd; padding: 13px; text-align: left;">Why it Matters</th>
<th style="border: 1px solid #ddd; padding: 13px; text-align: left;">Recommended Fix</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Hidden global leakage</td>
<td style="border: 1px solid #ddd; padding: 13px;">Declaring a variable without <code>let/const</code> creates an implicit global, which can be overwritten by another node’s script.</td>
<td style="border: 1px solid #ddd; padding: 13px;">Always use <code>let</code>/<code>const</code>. Add <code>"use strict";</code> at the top of the script.</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Version drift</td>
<td style="border: 1px solid #ddd; padding: 13px;">n8n upgrades may change the sandbox environment (e.g., Node.js version).</td>
<td style="border: 1px solid #ddd; padding: 13px;">Pin the Node.js version in your self‑hosted deployment or test against the exact <strong>n8n Docker image</strong> you run.</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Error masking</td>
<td style="border: 1px solid #ddd; padding: 13px;">A <code>try { … } catch (e) {}</code> that only logs <code>e.message</code> hides the stack trace, making future debugging harder.</td>
<td style="border: 1px solid #ddd; padding: 13px;">Log the full error: <code>this.logger.error(e.stack);</code> and re‑throw if the workflow should fail.</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Sensitive data exposure</td>
<td style="border: 1px solid #ddd; padding: 13px;">Logging full <code>items</code> can leak API keys or PII.</td>
<td style="border: 1px solid #ddd; padding: 13px;">Redact before logging: <code>const safe = items.map(i => ({ ...i, json: { ...i.json, apiKey: '[REDACTED]' } }));</code></td>
</tr>
</tbody>
</table>
<h2 style="margin-bottom: 45px; line-height: 1.3;"></h2>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">Conclusion</h2>
<p style="margin-bottom: 2em; line-height: 1.9;">ReferenceErrors in n8n Function nodes stem from undeclared or mis‑scoped identifiers. By declaring every variable, respecting node isolation, and using the built‑in <code>items</code> 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.</p>

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, or var.
- Pull data from other nodes via
items[0].json.<field> or await 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) for let foo, const foo, or var 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 via items.
• From other nodes: use items[0].json.<field> or await 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.log with this.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, or var.
- 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
async and await is only used on promises.
- Dynamic keys have a fallback (
const key = dynamicKey || 'default';).
- No stray
eval or new Function – they bypass static analysis and raise hidden reference issues.
- Remove debugging
console.log before 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.