Issue Debugging: Frontend (Replit) to Backend (n8n via ngrok) Communication - "Unexpected end of JSON input"

Problem Summary:

I am experiencing an issue where my frontend web application, hosted on Replit, is unable to correctly parse the JSON response from my backend automation workflow built with n8n, which is running locally and exposed to the internet via ngrok. The frontend consistently throws a “Error: Failed to execute ‘json’ on ‘Response’: Unexpected end of JSON input”, indicating that the backend is either returning an empty body or invalid JSON, despite evidence suggesting otherwise.

My Setup:

  • Frontend: HTML/JavaScript application hosted on Replit. The relevant code uses the fetch API to send a POST request to a webhook URL exposed by ngrok.
  • Backend: n8n (version unknown, running locally on port 5678).
  • ngrok: Used to create a public URL that tunnels to my local n8n instance.
  • Webhook: An n8n workflow with a “Webhook” trigger node, followed by an AI Agent node (e.g., OpenAI), and finally a “Respond to Webhook” node.
  • Webhook Configuration: The “Respond to Webhook” node is configured to respond with a 200 OK status and a Content-Type: application/json header. The response body is set using an expression to output a JSON object containing the AI Agent’s response.

What Works:

  • The initial POST request from the frontend successfully reaches the n8n webhook (visible in n8n executions).
  • The AI Agent node in n8n executes correctly and produces the desired output string.
  • The “Respond to Webhook” node in n8n executes after the AI Agent.
  • When a fixed JSON response body (e.g., {"response": "{{$json[\"output\"]}}"}) is used in the “Respond to Webhook” node, n8n’s execution logs indicate a successful response containing the AI’s output.

The Problem in Detail:

Despite n8n seemingly generating a valid JSON response (as seen in its logs with a fixed response body), the frontend fetch API consistently fails with the “Unexpected end of JSON input” error. This suggests that the frontend is receiving an empty response body or a response that it cannot interpret as valid JSON.

What I Have Already Tried (with no success):

  • Triggering the webhook manually via Postman or a simple browser fetch() call yields the same “Unexpected end of JSON input” error on the client side when n8n is configured to use an expression in the “Response Body” (e.g., {"response": $json.output}).
  • Returning simpler static JSON within the expression (e.g., {"response": "Test worked"}) in the “Respond to Webhook” node still results in the same frontend error.
  • Implementing fallback logic on the frontend (data.output || "No response") confirms that data is either undefined or doesn’t have the expected properties.
  • Confirmed that the AI Agent node’s output is a valid string under the "output" key in the n8n execution logs.
  • Explicitly set the Content-Type: application/json response header in the “Respond to Webhook” node.
  • Tried using the schema generated by n8n in the “Response Body” of the “Respond to Webhook” node while in expression mode, which resulted in an “Invalid JSON in ‘Response Body’ field” error within the n8n editor itself.
  • Used JSON.stringify() within the “Response Body” expression in n8n (e.g., JSON.stringify({ "response": $json.output })), which also resulted in the “Invalid JSON in ‘Response Body’ field” error within the n8n editor.
  • On the frontend, I’ve tried logging the raw Response object and reading the response as .text() before attempting .json() parsing. This revealed that the responseText often contains the expected JSON string, but JSON.parse() still fails with a SyntaxError: Unexpected token '\n' at position 2, suggesting extra newline characters in the response.
  • Implemented .trim() and .replace(/^\n+|\n+$/g, '') on the responseText in the frontend before parsing, but the SyntaxError persists.
  • Attempted to explicitly set CORS headers (Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers) in the n8n “Respond to Webhook” node.

Questions and Potential Areas for Investigation:

  • Why does the “Respond to Webhook” node seem to successfully generate a JSON response with a fixed body (as per n8n logs), but the frontend receives an empty or unparsable response?
  • Is there a known issue or specific configuration within n8n or ngrok that could be causing the response body to be lost or corrupted during transit?
  • Could there be a subtle issue with how n8n handles expressions within the “Response Body” in my specific environment?
  • Are there any specific ngrok configurations or limitations with free accounts that might affect response bodies?
  • Could the Replit hosting environment have any impact on how responses from external services are handled?

I am at a loss as to why this seemingly straightforward setup is failing. Any insights, suggestions for further debugging, or potential solutions would be greatly appreciated. I am happy to provide workflow exports or more detailed logs if needed.

hello @SEAN1

plase, share the workflow that causes the issues. And what is the output of the Respond to the Webhook node?

You can select all nodes with ctrl+a, copy it with ctrl+c. Then past the content here after pressing button </> with ctrl+v.