<p><img class="alignnone size-full wp-image-4460" src="https://flowgenius.in/wp-content/uploads/2026/01/Child-1-Cluster-10.png" alt="" /></p>
<p style="text-align: center;">Step by Step Guide to solve n8n Data Mapping Errors</p>
<p> </p>
<p> </p>
<hr />
<p> </p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Who this is for:</strong> Automation engineers and developers who build production‑grade n8n workflows that interact with external APIs. <strong>We cover this in detail in the</strong> n8n API Integration Errors Guide.</p>
<div style="margin: 55px 0;">
<hr />
</div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">Quick Diagnosis</h2>
<p style="margin-bottom: 2em; line-height: 1.9;">A malformed API payload in n8n almost always stems from a <strong>data‑mapping error</strong> – a wrong property name, a missing required field, or a type mismatch.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">Quick fix</h3>
<ol style="line-height: 1.9; margin-bottom: 1.8em;">
<li>Open the node that builds the payload (HTTP Request, Webhook, or connector).</li>
<li>Edit <strong>Parameters → Body</strong> (or the equivalent UI).</li>
<li>Use the <strong>Expression Builder</strong> to reference the exact source field, e.g. <code>{{$json["fieldName"]}}</code>.</li>
<li>Click <strong>Preview</strong> and verify that the JSON matches the API spec (all required keys, correct types).</li>
<li>Save → <strong>Run</strong> the workflow and confirm a 200/201 response in the Execution Log.</li>
</ol>
<p style="margin-bottom: 2em; line-height: 1.9;">*If the preview still shows errors, insert a <strong>Function</strong> node to transform the data before the request (see “Step‑by‑Step Debugging”).*</p>
<div style="margin: 55px 0;">
<hr />
</div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">1. Why Data Mapping Errors Break Your API Calls</h2>
<p><strong>If you encounter any</strong> <a href="/n8n-json-parse-errors">n8n json parse errors</a><strong> resolve them before continuing with the setup.</strong></p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Micro‑summary:</strong> This table maps common HTTP error symptoms to their typical data‑mapping root causes and shows how n8n surfaces them.</p>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="border: 1px solid #e0e0e0; padding: 13px;">Symptom</th>
<th style="border: 1px solid #e0e0e0; padding: 13px;">Typical Root Cause</th>
<th style="border: 1px solid #e0e0e0; padding: 13px;">How n8n Shows It</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">400 Bad Request – “missing required field”</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Source field not mapped or typo in target key</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Execution log → <code>Error: Bad Request – field “email” is required</code></td>
</tr>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">422 Unprocessable Entity – type mismatch</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Mapping a string to a numeric field (or vice‑versa)</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Execution log → <code>Error: “age” must be a number</code></td>
</tr>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">500 Internal Server Error – malformed JSON</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Extra commas, stray brackets, or undefined variables in the payload</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Execution log → <code>Error: Unexpected token … in JSON at position …</code></td>
</tr>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">No response / timeout</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Empty payload sent (all fields undefined)</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Execution log → <code>No request body sent</code></td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>EEFA note:</strong> In production, malformed payloads can trigger rate‑limit blocks or corrupt downstream data. Always validate payloads before hitting live endpoints.</p>
<div style="margin: 55px 0;">
<hr />
</div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">2. Understanding n8n’s Mapping Mechanics</h2>
<p><strong>If you encounter any</strong> <a href="/n8n-duplicate-record-errors">n8n duplicate record errors</a><strong> resolve them before continuing with the setup.</strong></p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Micro‑summary:</strong> Choose the right mapping mode to avoid “undefined” values.</p>
<ol style="line-height: 1.9; margin-bottom: 1.8em;">
<li><strong>Static values</strong> – entered directly in the UI (e.g., <code>status: "active"</code>).</li>
<li><strong>Expressions</strong> – <code>{{$json["field"]}}</code>, <code>{{$node["NodeName"].json["field"]}}</code>, or helper functions (<code>$number()</code>, <code>$join()</code>).</li>
<li><strong>JSON / RAW mode</strong> – you write the whole body as a JSON string; n8n does <strong>no</strong> automatic escaping.</li>
</ol>
<blockquote style="margin: 2em 0; padding: 1em; border-left: 4px solid #e0e0e0; background: #fafafa;">
<p style="margin: 0; line-height: 1.9;"><strong>Pro tip:</strong> Use <strong>Expression Mode</strong> for any value that pulls data from previous nodes. It guarantees runtime resolution and prevents “undefined” errors.</p>
</blockquote>
<div style="margin: 55px 0;">
<hr />
</div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">3. Common Data‑Mapping Pitfalls</h2>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Micro‑summary:</strong> Spot the most frequent mistakes and see the corrected pattern.</p>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="border: 1px solid #e0e0e0; padding: 13px;">Pitfall</th>
<th style="border: 1px solid #e0e0e0; padding: 13px;">Example (Wrong)</th>
<th style="border: 1px solid #e0e0e0; padding: 13px;">Corrected Example</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Typo in target key</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;"><code>"emial": "john@example.com"</code></td>
<td style="border: 1px solid #e0e0e0; padding: 13px;"><code>"email": "john@example.com"</code></td>
</tr>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Wrong source path</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;"><code>{{$json["user"]["email"]}}</code> (but data lives at <code>{{$json["contact"]["email"]}}</code>)</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;"><code>{{$json["contact"]["email"]}}</code></td>
</tr>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Missing brackets (invalid JSON)</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;"><code>"age": {{$json["age"]}}</code></td>
<td style="border: 1px solid #e0e0e0; padding: 13px;"><code>"age": {{$json["age"]}}</code> <em>(use JSON mode so the whole body stays valid)</em></td>
</tr>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Data‑type mismatch</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;"><code>"age": "30"</code> (API expects number)</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;"><code>"age": {{$number($json["age"])}}</code></td>
</tr>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Undefined variable</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;"><code>"id": {{$json["id"]}}</code> (upstream node didn’t output <code>id</code>)</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Add a <strong>Set</strong> node to create <code>id</code>, or use a fallback: <code>{{$json["id"] || "default-id"}}</code></td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>EEFA warning:</strong> Some APIs (e.g., Salesforce) reject payloads with <strong>null</strong> where a required field expects a non‑null value. Guard against accidental nulls with <code>$exists()</code>.</p>
<div style="margin: 55px 0;">
<hr />
</div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">4. Step‑by‑Step Debugging Workflow</h2>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.1. Isolate the Payload</h3>
<ol style="line-height: 1.9; margin-bottom: 1.8em;">
<li>Add a <strong>Set</strong> node directly before the failing request.</li>
<li>Create a field <code>debugPayload</code> that contains the same expression you use in the request body.</li>
</ol>
<p style="margin-bottom: 2em; line-height: 1.9;">Run the workflow in <strong>Execute Workflow</strong> mode and inspect <code>debugPayload</code> in the execution log.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.2. Validate JSON Structure</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">Copy the payload from the log and run it through <code>jq</code> (online or CLI) to catch syntax errors.</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;"># Replace <payload> with the JSON you copied
echo '<payload>' | jq .
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">If <code>jq</code> reports “parse error”, the JSON is malformed.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.3. Transform with a Function Node (when needed)</h3>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Purpose:</strong> Convert a CSV string into an array of objects before sending it to the API.</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">// Split CSV into lines
const csv = $json["csvData"]; // e.g. "name,age\nJohn,30\nJane,25"
const lines = csv.split('\n');
</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">// Extract headers
const headers = lines.shift().split(',');
</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">// Build an array of objects
return lines.map(line => {
const values = line.split(',');
return headers.reduce((obj, header, i) => {
obj[header] = values[i];
return obj;
}, {});
});
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Connect the Function node’s output to the HTTP Request body and reference it with <code>{{$json}}</code>.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.4. Re‑run & Verify</h3>
<ul style="line-height: 1.9; margin-bottom: 1.8em;">
<li>Check the <strong>Response Code</strong> in the Execution Log.</li>
<li>If it still fails, repeat the isolation step on the **previous node** to ensure upstream data is correct.</li>
</ul>
<div style="margin: 55px 0;">
<hr />
</div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">5. Checklist: Preventing Data‑Mapping Errors Before They Hit Production</h2>
<ul style="line-height: 1.9; margin-bottom: 1.8em;">
<li><strong>Schema Alignment</strong> – Compare the API’s OpenAPI/Swagger spec with your payload keys.</li>
<li><strong>Type Casting</strong> – Use <code>$number()</code>, <code>$string()</code>, <code>$boolean()</code> for all non‑string fields.</li>
<li><strong>Existence Guard</strong> – Wrap optional fields: <code>$exists($json["field"]) ? $json["field"] : null</code>.</li>
<li><strong>JSON Validation</strong> – Run payloads through <code>jq</code> or a JSON‑schema validator in a **Test** node.</li>
<li><strong>Version Control</strong> – Export the workflow JSON, store it in Git, and diff changes to spot accidental key removals.</li>
<li><strong>Error‑Handling Node</strong> – Add an **Error Trigger** that logs the failing payload to a Google Sheet for post‑mortem analysis.</li>
</ul>
<div style="margin: 55px 0;">
<hr />
</div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">6. Real‑World Example: Syncing Leads to HubSpot</h2>
<h3 style="margin-bottom: 45px; line-height: 1.3;">6.1. Faulty Mapping (What went wrong)</h3>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"properties": {
"firstname": "{{$json["first_name"]}}",
"lastname": "{{$json["last_name"]}}",
"email": "{{$json["contact_email"]}}"
}
}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;"><em>Issue:</em> Source column is actually <code>email_address</code>, not <code>contact_email</code>.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">6.2. Corrected Mapping</h3>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"properties": {
"firstname": "{{$json["first_name"]}}",
"lastname": "{{$json["last_name"]}}",
"email": "{{$json["email_address"]}}"
}
}
</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">6.3. Adding Type Safety</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">HubSpot expects strings for both <code>email</code> and <code>phone</code>. Enforce this with explicit casting:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"properties": {
"email": "{{$string($json["email_address"])}}",
"phone": "{{$string($json["phone_number"] || "")}}"
}
}
</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">6.4. Validation Step (Function Node)</h3>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">if (!$json.email) {
throw new Error("Email is missing – cannot create HubSpot contact");
}
return $json;
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>EEFA note:</strong> HubSpot silently drops records missing required fields, leading to data loss. The guard forces the workflow to fail fast and alert you.</p>
<div style="margin: 55px 0;">
<hr />
</div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">7. When to Use “Raw” JSON vs. UI Mapping</h2>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="border: 1px solid #e0e0e0; padding: 13px;">Use‑Case</th>
<th style="border: 1px solid #e0e0e0; padding: 13px;">Recommended Mode</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Simple key/value pairs, <strong>no transformation</strong></td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">UI Mapping (Expression Builder)</td>
</tr>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Complex nested objects, <strong>arrays</strong>, or conditional fields</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">**Raw JSON** mode with embedded expressions</td>
</tr>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Need to <strong>reuse the same payload</strong> across multiple nodes</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Store payload in a **Set** node and reference <code>$json["payload"]</code></td>
</tr>
<tr>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Working with <strong>binary data</strong> (files, base64)</td>
<td style="border: 1px solid #e0e0e0; padding: 13px;">Use **Binary Data** field, not JSON</td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Tip:</strong> Even in Raw mode, keep each expression on its own line for readability; n8n will still render the final JSON correctly.</p>
<hr />
<h2 style="margin-bottom: 45px; line-height: 1.3;">9. FAQ</h2>
<h3 style="margin-bottom: 45px; line-height: 1.3;">Q1. How can I see the exact JSON that n8n sends?</h3>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Answer:</strong> In the Execution Log, open the **Request** tab of the HTTP Request node. The **Body** section displays the resolved JSON. Use **Copy to Clipboard** for external validation.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">Q2. My payload contains a date in <code>YYYY‑MM‑DD</code> but the API expects ISO‑8601.</h3>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Answer:</strong> Wrap the date with <code>$date($json["date"], { format: "YYYY-MM-DD", output: "ISO" })</code>.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">Q3. The workflow works in the editor but fails in production.</h3>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Answer:</strong> Check **environment variables** – you may be referencing a dev‑only variable (<code>{{$env["API_KEY_DEV"]}}</code>). Use <code>$env["API_KEY"]</code> consistently across environments.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">Q4. Can I test payloads without calling the real API?</h3>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Answer:</strong> Yes. Insert a **Webhook** node after the mapping node, set it to **Respond to Webhook**, and trigger the workflow manually. The webhook response will contain the payload.</p>
<div style="margin: 55px 0;">
<hr />
</div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">Conclusion</h2>
<p style="margin-bottom: 2em; line-height: 1.9;">By systematically diagnosing data‑mapping errors—isolating the payload, validating JSON, enforcing type safety, and guarding against missing fields—you eliminate malformed payloads, keep external APIs happy, and maintain high‑throughput, production‑grade n8n automations. Apply the checklist and debugging steps on every new integration to ensure reliable, error‑free data exchange.</p>

Step by Step Guide to solve n8n Data Mapping Errors
Who this is for: Automation engineers and developers who build production‑grade n8n workflows that interact with external APIs. We cover this in detail in the n8n API Integration Errors Guide.
Quick Diagnosis
A malformed API payload in n8n almost always stems from a data‑mapping error – a wrong property name, a missing required field, or a type mismatch.
Quick fix
- Open the node that builds the payload (HTTP Request, Webhook, or connector).
- Edit Parameters → Body (or the equivalent UI).
- Use the Expression Builder to reference the exact source field, e.g.
{{$json["fieldName"]}}.
- Click Preview and verify that the JSON matches the API spec (all required keys, correct types).
- Save → Run the workflow and confirm a 200/201 response in the Execution Log.
*If the preview still shows errors, insert a Function node to transform the data before the request (see “Step‑by‑Step Debugging”).*
1. Why Data Mapping Errors Break Your API Calls
If you encounter any n8n json parse errors resolve them before continuing with the setup.
Micro‑summary: This table maps common HTTP error symptoms to their typical data‑mapping root causes and shows how n8n surfaces them.
| Symptom |
Typical Root Cause |
How n8n Shows It |
| 400 Bad Request – “missing required field” |
Source field not mapped or typo in target key |
Execution log → Error: Bad Request – field “email” is required |
| 422 Unprocessable Entity – type mismatch |
Mapping a string to a numeric field (or vice‑versa) |
Execution log → Error: “age” must be a number |
| 500 Internal Server Error – malformed JSON |
Extra commas, stray brackets, or undefined variables in the payload |
Execution log → Error: Unexpected token … in JSON at position … |
| No response / timeout |
Empty payload sent (all fields undefined) |
Execution log → No request body sent |
EEFA note: In production, malformed payloads can trigger rate‑limit blocks or corrupt downstream data. Always validate payloads before hitting live endpoints.
2. Understanding n8n’s Mapping Mechanics
If you encounter any n8n duplicate record errors resolve them before continuing with the setup.
Micro‑summary: Choose the right mapping mode to avoid “undefined” values.
- Static values – entered directly in the UI (e.g.,
status: "active").
- Expressions –
{{$json["field"]}}, {{$node["NodeName"].json["field"]}}, or helper functions ($number(), $join()).
- JSON / RAW mode – you write the whole body as a JSON string; n8n does no automatic escaping.
Pro tip: Use Expression Mode for any value that pulls data from previous nodes. It guarantees runtime resolution and prevents “undefined” errors.
3. Common Data‑Mapping Pitfalls
Micro‑summary: Spot the most frequent mistakes and see the corrected pattern.
| Pitfall |
Example (Wrong) |
Corrected Example |
| Typo in target key |
"emial": "john@example.com" |
"email": "john@example.com" |
| Wrong source path |
{{$json["user"]["email"]}} (but data lives at {{$json["contact"]["email"]}}) |
{{$json["contact"]["email"]}} |
| Missing brackets (invalid JSON) |
"age": {{$json["age"]}} |
"age": {{$json["age"]}} (use JSON mode so the whole body stays valid) |
| Data‑type mismatch |
"age": "30" (API expects number) |
"age": {{$number($json["age"])}} |
| Undefined variable |
"id": {{$json["id"]}} (upstream node didn’t output id) |
Add a Set node to create id, or use a fallback: {{$json["id"] || "default-id"}} |
EEFA warning: Some APIs (e.g., Salesforce) reject payloads with null where a required field expects a non‑null value. Guard against accidental nulls with $exists().
4. Step‑by‑Step Debugging Workflow
4.1. Isolate the Payload
- Add a Set node directly before the failing request.
- Create a field
debugPayload that contains the same expression you use in the request body.
Run the workflow in Execute Workflow mode and inspect debugPayload in the execution log.
4.2. Validate JSON Structure
Copy the payload from the log and run it through jq (online or CLI) to catch syntax errors.
# Replace <payload> with the JSON you copied
echo '<payload>' | jq .
If jq reports “parse error”, the JSON is malformed.
4.3. Transform with a Function Node (when needed)
Purpose: Convert a CSV string into an array of objects before sending it to the API.
// Split CSV into lines
const csv = $json["csvData"]; // e.g. "name,age\nJohn,30\nJane,25"
const lines = csv.split('\n');
// Extract headers
const headers = lines.shift().split(',');
// Build an array of objects
return lines.map(line => {
const values = line.split(',');
return headers.reduce((obj, header, i) => {
obj[header] = values[i];
return obj;
}, {});
});
Connect the Function node’s output to the HTTP Request body and reference it with {{$json}}.
4.4. Re‑run & Verify
- Check the Response Code in the Execution Log.
- If it still fails, repeat the isolation step on the **previous node** to ensure upstream data is correct.
5. Checklist: Preventing Data‑Mapping Errors Before They Hit Production
- Schema Alignment – Compare the API’s OpenAPI/Swagger spec with your payload keys.
- Type Casting – Use
$number(), $string(), $boolean() for all non‑string fields.
- Existence Guard – Wrap optional fields:
$exists($json["field"]) ? $json["field"] : null.
- JSON Validation – Run payloads through
jq or a JSON‑schema validator in a **Test** node.
- Version Control – Export the workflow JSON, store it in Git, and diff changes to spot accidental key removals.
- Error‑Handling Node – Add an **Error Trigger** that logs the failing payload to a Google Sheet for post‑mortem analysis.
6. Real‑World Example: Syncing Leads to HubSpot
6.1. Faulty Mapping (What went wrong)
{
"properties": {
"firstname": "{{$json["first_name"]}}",
"lastname": "{{$json["last_name"]}}",
"email": "{{$json["contact_email"]}}"
}
}
Issue: Source column is actually email_address, not contact_email.
6.2. Corrected Mapping
{
"properties": {
"firstname": "{{$json["first_name"]}}",
"lastname": "{{$json["last_name"]}}",
"email": "{{$json["email_address"]}}"
}
}
6.3. Adding Type Safety
HubSpot expects strings for both email and phone. Enforce this with explicit casting:
{
"properties": {
"email": "{{$string($json["email_address"])}}",
"phone": "{{$string($json["phone_number"] || "")}}"
}
}
6.4. Validation Step (Function Node)
if (!$json.email) {
throw new Error("Email is missing – cannot create HubSpot contact");
}
return $json;
EEFA note: HubSpot silently drops records missing required fields, leading to data loss. The guard forces the workflow to fail fast and alert you.
7. When to Use “Raw” JSON vs. UI Mapping
| Use‑Case |
Recommended Mode |
| Simple key/value pairs, no transformation |
UI Mapping (Expression Builder) |
| Complex nested objects, arrays, or conditional fields |
**Raw JSON** mode with embedded expressions |
| Need to reuse the same payload across multiple nodes |
Store payload in a **Set** node and reference $json["payload"] |
| Working with binary data (files, base64) |
Use **Binary Data** field, not JSON |
Tip: Even in Raw mode, keep each expression on its own line for readability; n8n will still render the final JSON correctly.
9. FAQ
Q1. How can I see the exact JSON that n8n sends?
Answer: In the Execution Log, open the **Request** tab of the HTTP Request node. The **Body** section displays the resolved JSON. Use **Copy to Clipboard** for external validation.
Q2. My payload contains a date in YYYY‑MM‑DD but the API expects ISO‑8601.
Answer: Wrap the date with $date($json["date"], { format: "YYYY-MM-DD", output: "ISO" }).
Q3. The workflow works in the editor but fails in production.
Answer: Check **environment variables** – you may be referencing a dev‑only variable ({{$env["API_KEY_DEV"]}}). Use $env["API_KEY"] consistently across environments.
Q4. Can I test payloads without calling the real API?
Answer: Yes. Insert a **Webhook** node after the mapping node, set it to **Respond to Webhook**, and trigger the workflow manually. The webhook response will contain the payload.
Conclusion
By systematically diagnosing data‑mapping errors—isolating the payload, validating JSON, enforcing type safety, and guarding against missing fields—you eliminate malformed payloads, keep external APIs happy, and maintain high‑throughput, production‑grade n8n automations. Apply the checklist and debugging steps on every new integration to ensure reliable, error‑free data exchange.