Proxy timeout errors stopped during long AI agent runs
Long-running AI agents now complete cleanly without reverse proxies injecting HTML error pages into chat streams. Three defensive layers prevent connection timeouts.
When AI agents take more than 100 seconds to complete, reverse proxies like Cloudflare terminate idle connections and inject HTML error pages into the chat stream. Users see garbled markup in their chat panels even when the agent finishes successfully.
This fix adds three layers of protection. First, socket configuration prevents TCP-level idle timeouts with the same settings already used for server-sent events. Second, a heartbeat writes a JSON keepalive chunk every 30 seconds while an execution is active, keeping the connection alive through proxies. Third, the frontend detects injected HTML error pages and replaces them with a clear user message.
The heartbeat is tied to the execution lifecycle — it starts when execution begins and stops when it finishes, so timeouts still fire independently if something hangs. The frontend parser also skips the keepalive chunks, so they don't appear as chat messages.
Users running long AI agents like Browserbase browser automation should now see clean responses instead of HTML corruption.
View Original GitHub Description
Summary
When a long-running AI Agent tool call (e.g. Browserbase browser agent ~3 min) produces no streaming chunks, reverse proxies like Cloudflare time out the idle connection (~100s) and inject a raw 524 error HTML page into the chat stream. The user sees jumbled HTML markup in the chat panel even though the agent eventually completes successfully.
This PR fixes the issue with three layers:
-
Socket configuration (ChatTrigger.node.ts) — Apply the same socket settings the SSE push path uses (
setTimeout(0),setNoDelay(true),setKeepAlive(true)) to prevent TCP-level idle timeouts. -
Execution-bound heartbeat (workflow-runner.ts) — Write an empty
\nevery 30s to the chunked response while the execution is active. The heartbeat is tied to the execution lifecycle viaworkflowExecuteAfterhook, so it does not outlive the execution or mask real timeouts (EXECUTIONS_TIMEOUTstill fires independently). The frontend line parser already skips empty lines. -
Frontend HTML guard (chat message.ts) — In
createLineParser(), skip non-JSON lines containing<!DOCTYPEor<htmlinstead of rendering them as chat text. Defense-in-depth if a proxy still injects HTML despite layers 1 and 2.
How to test
- Set up a Chat Trigger workflow with a long-running AI Agent tool (e.g. Browserbase agent that takes >100s)
- Deploy behind Cloudflare or a reverse proxy with an idle timeout
- Send a chat message and wait for the tool to complete
- Verify no HTML error appears in the chat — only the agent's actual response
Related Linear tickets, Github issues, and Community forum posts
https://linear.app/n8n/issue/AI-2319
Review / Merge checklist
- PR title and summary are descriptive. (conventions)
- Docs updated or follow-up ticket created.
- Tests included.
- PR Labeled with
release/backport(if the PR is an urgent fix that needs to be backported)