Getting JSON format error in n8n contact scraper workflow

JSON parsing issue in my contact extraction workflow

I’m building a contact scraper using n8n and getting this error in my subworkflow:

The ‘JSON Output’ in item 0 contains invalid JSON.

The main workflow uses a chatbot agent that calls a subworkflow to extract contacts and save them to Google Sheets. Here’s my main workflow setup:

{
  "name": "contactExtractor",
  "nodes": [
    {
      "parameters": {
        "name": "contactScraping",
        "description": "=Use this to extract contacts when you have search details.\n\nInput format:\n\n[\n  {\n    \"region\": [\n      \"REGION1+HERE\",\n      \"REGION2+HERE\"\n    ],\n    \"industry\": [\n      \"INDUSTRY1+HERE\",\n      \"INDUSTRY2+HERE\"\n    ],\n    \"position\": [\n      \"POSITION1+HERE\",\n      \"POSITION2+HERE\"\n    ]\n  }\n]",
        "workflowId": {
          "__rl": true,
          "value": "9XkbvWIetP2d0KBz",
          "mode": "list",
          "cachedResultName": "Contact Sub-Workflow"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "position": [100, 200],
      "id": "c160a514-fc69-4b5b-b545-ee987836a821",
      "name": "contactScraping"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.message.text }}",
        "options": {
          "systemMessage": "=# System\nYou extract business contacts from databases.\n\n# Available Tools\n### contactScraping:\nExtract contacts to spreadsheet after getting search criteria.\n\n# Instructions\n- Introduce yourself as Contact Extractor\n- Ask what contacts they need today\n- Replace spaces with '+' in queries\n- Example: 'new york usa' becomes 'new+york+usa'\n\n# Sample Flow\n- User: 'Hello'\n- Bot: 'Hi! I'm Contact Extractor. What contacts do you want to find?'\n- User: 'Marketing managers in London'\n- Bot: 'Great! What industries should I focus on?'\n- User: 'Tech companies'\n- Tool call with proper JSON format"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [-160, -40],
      "id": "15090ffe-d584-4154-b279-eaaaf800519b",
      "name": "Contact Agent"
    }
  ]
}

And my subworkflow that’s causing the JSON error:

{
  "name": "Contact Sub-Workflow",
  "nodes": [
    {
      "parameters": {
        "mode": "raw",
        "jsonOutput": "={\n\"searchParams\":\n{{ $json.searchData }}\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "position": [-680, 160],
      "id": "gbe8dece-f3d0-464f-a621-4fd4a0fd1182",
      "name": "Parse JSON"
    },
    {
      "parameters": {
        "url": "https://api.hunter.io/v2/domain-search",
        "sendBody": true,
        "jsonBody": "={\n    \"domain\": \"{{ $json.targetDomain }}\",\n    \"limit\": 100,\n    \"type\": \"professional\"\n}"
      },
      "type": "n8n-nodes-base.httpRequest",
      "position": [-320, 160],
      "id": "b94b7dac-facb-4111-8c99-aec46d6e082g",
      "name": "Contact API"
    }
  ]
}

The error happens at the Parse JSON node. I want to extract contacts to my spreadsheet but can’t get past this JSON validation issue. Any ideas what’s wrong with my JSON structure?

Your Parse JSON node is the problem. You’re using raw mode with {{ $json.searchData }} but raw mode expects valid JSON - this creates malformed output. Switch to a regular Set node instead. Add a parameter called ‘searchParams’ with the value {{ $json.searchData }}. Raw mode only works when you need exact JSON strings, but you want n8n to process the expressions first. I’ve seen tons of people get tripped up by this - raw mode doesn’t evaluate expressions like you’d expect. Also double-check that your main workflow is actually passing searchData to the subworkflow correctly. The tool might not be sending the data structure you think it is.

The Problem:

You’re encountering a “The ‘JSON Output’ in item 0 contains invalid JSON” error in your n8n workflow when trying to extract contacts using a subworkflow and the Hunter.io API. This error originates from the “Parse JSON” node in your subworkflow, specifically due to how you’re handling the {{ $json.searchData }} expression within the JSON structure.

:thinking: Understanding the “Why” (The Root Cause):

The issue lies in the misuse of the “raw” mode in your n8n Set node (“Parse JSON”). Raw mode expects a complete, valid JSON string as input. However, you’re attempting to inject the dynamic expression {{ $json.searchData }} directly into a JSON structure within the raw mode. n8n’s expression engine doesn’t evaluate expressions inside a JSON string that’s being treated as raw. The result is that the node receives malformed JSON, hence the error. Simply put, you’re asking n8n to parse JSON that’s still containing n8n expression language, which it can’t do directly in raw mode. This is a common mistake when working with dynamic JSON data in n8n.

:gear: Step-by-Step Guide:

  1. Replace the “Parse JSON” Node: Delete the existing “Parse JSON” node (ID: gbe8dece-f3d0-464f-a621-4fd4a0fd1182) in your subworkflow. Replace it with a standard n8n “Set” node. This node operates in a manner that correctly evaluates n8n expressions before constructing the JSON.

  2. Configure the New “Set” Node: In the new Set node, set the following:

    • Mode: Change this to the default “normal” mode (not “raw”).
    • Add a new Parameter: Add a parameter named "searchParams".
    • Set the Value: Set the value of the "searchParams" parameter to {{ $json.searchData }}. This will correctly pass the evaluated searchData as a parameter.
  3. Test and Verify: Save your changes and rerun your workflow. The error should now be resolved. If it persists, proceed to step 4.

  4. Debug Incoming Data: If the problem remains, add a debug node before the “Set” node to inspect the contents of the $json.searchData variable. This will help you verify that your main workflow is correctly sending the expected data structure to the subworkflow. Ensure $json.searchData contains the correct information before moving onto the next step. Look for unexpected characters or data types that might cause problems.

  5. Review Main Workflow: Ensure that your main workflow (workflow ID: 9XkbvWIetP2d0KBz) is indeed passing the correct searchData JSON to the subworkflow. Inspect the data sent to confirm it matches the structure you’re expecting in the subworkflow.

:mag: Common Pitfalls & What to Check Next:

  • Incorrect Data Structure: Verify the format of the searchData object being passed. Ensure it’s a valid JSON object and that the keys (region, industry, position) are correctly structured.
  • Missing or Incorrect API Key: Double check that your Hunter.io API key is correctly configured in the “Contact API” node.
  • Hunter.io API Limits: Hunter.io might have rate limits. If you’re making many requests, you may need to implement rate limiting or error handling to avoid API request failures.
  • API Response Handling: After successfully retrieving data from the Hunter.io API, ensure you handle the API response correctly and map it to your Google Sheet. Add additional nodes to process and clean the API response.

:speech_balloon: Still running into issues? Share your (sanitized) config files, the exact command you ran, and any other relevant details. The community is here to help!

Your JSON syntax is broken in the Parse JSON node. You’ve got {{ $json.searchData }} inside the JSON but it needs proper quotes. Change it to "searchParams": "{{ $json.searchData }}" or if searchData is already JSON, use "searchParams": {{ $json.searchData }} without the extra quotes.

Your Parse JSON node’s jsonOutput expression is the problem. You’re mixing JSON syntax with n8n expressions wrong. That {{ $json.searchData }} line without quotes breaks everything if searchData has strings or arrays. Had this same issue last month building a similar workflow. Fix it like this: ={ "searchParams": $json.searchData } - let n8n handle the JSON conversion instead of doing it manually. Also throw a debug node before Parse JSON to see what searchData actually looks like. Half the time the incoming data isn’t what you think it is and needs cleanup first.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.