Zie619/n8n-workflows · error · Error

Invalid input data format

Error message

Invalid input data format

What it means

Thrown by the 'Parse Data' Code node when $json.data is absent, i.e. the item coming from the previous HTTP request node does not carry the expected data field containing a JSON string. The node JSON.parses $json.data and splits parsedData.reply.available / .unavailable into Domain/Availability rows for Excel export. Any upstream response that changes shape (error body, envelope change, empty reply) breaks the guard.

Source

Thrown at workflows/Wait/1954_Wait_Code_Automation_Webhook.json:153

      "parameters": {
        "url": "{{ $env.BASE_URL }}",
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 5000,
      "notes": "This httpRequest node performs automated tasks as part of the workflow."
    },
    {
      "id": "c4f38893-636a-4293-9e10-395be30683d0",
      "name": "Parse Data",
      "type": "n8n-nodes-base.code",
      "position": [
        500,
        -200
      ],
      "parameters": {
        "jsCode": "// Ensure input data exists\nif (!$json || !$json.data) {\n    throw new Error(\"Invalid input data format\");\n}\n\n// Parse the JSON string inside `data`\nlet parsedData;\ntry {\n    parsedData = JSON.parse($json.data);\n} catch (error) {\n    throw new Error(\"Error parsing JSON data: \" + error.message);\n}\n\n// Extract available and unavailable domains safely\nconst availableDomains = parsedData.reply?.available ? Object.values(parsedData.reply.available) : [];\nconst unavailableDomains = parsedData.reply?.unavailable ? Object.values(parsedData.reply.unavailable) : [];\n\n// Prepare the output array\nconst output = [];\n\n// Process available domains\navailableDomains.forEach(domainObj => {\n    if (domainObj && domainObj.domain) {\n        output.push({\n            Domain: domainObj.domain,\n            Availability: \"Available\"\n        });\n    }\n});\n\n// Process unavailable domains\nunavailableDomains.forEach(domain => {\n    if (typeof domain === \"string\") {\n        output.push({\n            Domain: domain,\n            Availability: \"Unavailable\"\n        });\n    } else if (typeof domain === \"object\" && domain.domain) {\n        output.push({\n            Domain: domain.domain,\n            Availability: \"Unavailable\"\n        });\n    }\n});\n\n// Return the structured data\nreturn output;"
      },
      "typeVersion": 2,
      "notes": "This code node performs automated tasks as part of the workflow."
    },
    {
      "id": "ec7b8311-65b7-45b0-85ae-b91d7c82e123",
      "name": "Convert to Excel",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        500,
        0
      ],
      "parameters": {
        "options": {
          "fileName": "domain_results.xlsx"
        },
        "operation": "xlsx",
        "binaryPropertyName": "={{ $json.MergedDomains }}"

View on GitHub (pinned to 94007c1445)

Solutions

  1. Execute the HTTP node standalone and inspect its output keys to see what the API actually returned (often an error message explains it).
  2. If $json.data can be an object, handle both: typeof d === 'string' ? JSON.parse(d) : d.
  3. Add an IF node on the HTTP response status/code so error payloads route to an error branch before parsing.
  4. Fix auth/rate-limit on the upstream API if error envelopes are the cause.

Example fix

// before
if (!$json || !$json.data) {
    throw new Error("Invalid input data format");
}
let parsedData;
try {
    parsedData = JSON.parse($json.data);
} catch (error) {
    throw new Error("Error parsing JSON data: " + error.message);
}

// after - accept object or string, report the real shape
if (!$json || (!$json.data && !$json.reply)) {
    throw new Error(`Invalid input data format. Item keys: ${$json ? Object.keys($json).join(', ') : 'null'}`);
}
const raw = $json.data ?? $json;
const parsedData = typeof raw === 'string' ? JSON.parse(raw) : raw;
Defensive patterns

Strategy: try-catch

Validate before calling

if (!$json || (!$json.data && !$json.reply)) {
  throw new Error(`Invalid input data format. Keys: ${$json ? Object.keys($json).join(', ') : 'null'}`);
}
const raw = $json.data ?? $json;
const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;
if (!parsed?.reply) {
  throw new Error(`Unexpected API envelope: ${JSON.stringify(parsed).slice(0, 200)}`);
}

Type guard

const hasDomainReply = (p) => p != null && p.reply != null &&
  (p.reply.available != null || p.reply.unavailable != null);

Try / catch

try {
  const parsed = typeof $json.data === 'string' ? JSON.parse($json.data) : $json.data;
  if (!parsed?.reply) throw new Error('API envelope missing .reply');
  return toRows(parsed);
} catch (e) {
  throw new Error(`Parse Data failed: ${e.message}; body preview: ${JSON.stringify($json).slice(0, 200)}`);
}

Prevention

When it happens

Trigger: The domain-availability API returned an error envelope (e.g., {error: 'rate limited'}) with no .data, the response was already parsed to an object so $json.data is an object (guard passes but JSON.parse throws the sibling error), a proxy/queue step renamed the field, or the HTTP node returned the raw body under a different property.

Common situations: API outage or auth expiry returning HTML/JSON error instead of the normal payload, response-format option on the HTTP Request node changed (String vs JSON), or upstream API version bump re-wrapping the reply.

Related errors


AI-assisted analysis of Zie619/n8n-workflows@94007c1445 (2026-08-15). Data as JSON: /api/errors/970d104488e37d61. Report an issue: GitHub.