Environment
- n8n-mcp: 2.73.0 (npx, up to date)
- n8n: 2.34.6
- Node: v24.19.0, Windows 11, non-Docker
- Transport: local MCP server (stdio)
Full "Connection closed" with no JSON error body in every case (server visibly restarts between calls; read-only calls like n8n_health_check / n8n_get_workflow in structure/minimal mode keep working throughout). Not a duplicate of #737 (that was a graceful VALIDATION_ERROR/_zod body from n8n 2.16 schema rejection, fixed via whitelisting) or #864 (uuid ESM crash, fixed by pinning uuid to ^11 — already the case in 2.73.0).
I found two independent crash causes by toggling validateNodes/validateConnections/validateExpressions one at a time. I no longer have a live repro for Bug B (I fixed the underlying data), but I'm reporting both since Bug B is a real "valid input, but wrong shape triggers a hard crash instead of an error" bug in n8n-mcp itself.
Bug A — intermittent crash when 2 of the 3 validation types run together
Default n8n_validate_workflow options (profile runtime, i.e. validateNodes/validateConnections/validateExpressions all default true) sometimes crash on a normal, non-trivial workflow (9 nodes: Gmail trigger → Postgres → Code → IF → Postgres, nothing exotic, no unusual field content).
Isolating by toggling each option pairwise, on the same workflow, in the same session:
- All three
true (default) → crashes most of the time
- Any single option
false (i.e. only one of the three validation types disabled) → still crashes about as often
- Key finding: it is NOT deterministic. The exact same call (
{validateConnections: false}, i.e. nodes+expressions only) on the exact same workflow crashed once, then succeeded on immediate retry, then I saw the same flip-flop on other pairings too.
Not reproducible on a synthetic 2-node workflow (manualTrigger → noOp) with all validations on — so it seems to need some amount of real node/expression complexity to trigger, but beyond that the trigger condition looks more like a race condition or resource issue (memory pressure? something not cleaned up between calls?) than a clean "these options together always crash" bug. n8n_update_partial_workflow with validateOnly: true on the same workflow shows the same intermittent crash, consistent with it running the same validation path internally.
Bug B (now fixed on my end, but worth reporting) — a node with a large corrupted-mojibake field crashed every tool call touching it, deterministically
Unrelated production workflow (21 nodes) had two Code nodes where a single accented character in a comment/regex had been mis-encoded repeatedly (classic multi-pass mojibake) into an ~11,500-character garbage blob — each affected node's jsCode ended up 18–33 KB total (not huge, but with a large pathological repeated-garbage substring inside).
While that content was present, this was 100% deterministic, unlike Bug A:
n8n_get_workflow({mode: "filtered", nodeNames: ["<affected node>"]}) → crashed every time
n8n_get_workflow({mode: "filtered", nodeNames: ["<sibling node, clean content>"]}) → succeeded every time, same workflow
n8n_validate_workflow on this workflow → crashed with any single validation type alone (unlike Bug A, which needs 2+ together and is flaky)
n8n_update_partial_workflow (validateOnly, trivial no-op) → crashed every time
I fixed the underlying data directly (reconstructed the correct single character from context and replaced the corrupted blob via SQL, bypassing n8n-mcp entirely), and confirmed all of the above now succeed cleanly. So I can't hand you a live repro workflow, but a synthetic repro should be easy: create a Code node whose jsCode contains a long (~10K+ char) run of unusual/repeated non-ASCII bytes (e.g. 'Ã'.repeat(10000) type content) inside a comment or string literal, and call n8n_get_workflow with mode: "filtered" targeting just that node, or n8n_validate_workflow with a single validation type. My guess is a regex somewhere (maybe a secret-scanner, sanitizer, or Unicode-normalization step) hitting catastrophic backtracking on the repeated pattern, or a response large/malformed enough to break the stdio framing without a caught error — I don't have server-side logs to confirm which.
Impact
Both are core tools. Bug A makes n8n_validate_workflow/n8n_update_partial_workflow unreliable enough that I stopped trusting a single "no crash" result as confirmation. Bug B forced a fallback to raw SQL against workflow_entity to fix a workflow at all, bypassing workflow_history/versionId bookkeeping (a separate but related footgun: n8n export:workflow without --published/--version resolves through versionId, not the live nodes column, so a SQL fix "disappears" from the CLI export until something else triggers a proper save).
Happy to share more detail (the exact 9-node structure for Bug A, or help building a synthetic Bug B repro) if useful.
Environment
Full "Connection closed" with no JSON error body in every case (server visibly restarts between calls; read-only calls like n8n_health_check / n8n_get_workflow in
structure/minimalmode keep working throughout). Not a duplicate of #737 (that was a gracefulVALIDATION_ERROR/_zodbody from n8n 2.16 schema rejection, fixed via whitelisting) or #864 (uuid ESM crash, fixed by pinning uuid to ^11 — already the case in 2.73.0).I found two independent crash causes by toggling
validateNodes/validateConnections/validateExpressionsone at a time. I no longer have a live repro for Bug B (I fixed the underlying data), but I'm reporting both since Bug B is a real "valid input, but wrong shape triggers a hard crash instead of an error" bug in n8n-mcp itself.Bug A — intermittent crash when 2 of the 3 validation types run together
Default
n8n_validate_workflowoptions (profileruntime, i.e. validateNodes/validateConnections/validateExpressions all defaulttrue) sometimes crash on a normal, non-trivial workflow (9 nodes: Gmail trigger → Postgres → Code → IF → Postgres, nothing exotic, no unusual field content).Isolating by toggling each option pairwise, on the same workflow, in the same session:
true(default) → crashes most of the timefalse(i.e. only one of the three validation types disabled) → still crashes about as often{validateConnections: false}, i.e. nodes+expressions only) on the exact same workflow crashed once, then succeeded on immediate retry, then I saw the same flip-flop on other pairings too.Not reproducible on a synthetic 2-node workflow (manualTrigger → noOp) with all validations on — so it seems to need some amount of real node/expression complexity to trigger, but beyond that the trigger condition looks more like a race condition or resource issue (memory pressure? something not cleaned up between calls?) than a clean "these options together always crash" bug.
n8n_update_partial_workflowwithvalidateOnly: trueon the same workflow shows the same intermittent crash, consistent with it running the same validation path internally.Bug B (now fixed on my end, but worth reporting) — a node with a large corrupted-mojibake field crashed every tool call touching it, deterministically
Unrelated production workflow (21 nodes) had two Code nodes where a single accented character in a comment/regex had been mis-encoded repeatedly (classic multi-pass mojibake) into an ~11,500-character garbage blob — each affected node's
jsCodeended up 18–33 KB total (not huge, but with a large pathological repeated-garbage substring inside).While that content was present, this was 100% deterministic, unlike Bug A:
n8n_get_workflow({mode: "filtered", nodeNames: ["<affected node>"]})→ crashed every timen8n_get_workflow({mode: "filtered", nodeNames: ["<sibling node, clean content>"]})→ succeeded every time, same workflown8n_validate_workflowon this workflow → crashed with any single validation type alone (unlike Bug A, which needs 2+ together and is flaky)n8n_update_partial_workflow(validateOnly, trivial no-op) → crashed every timeI fixed the underlying data directly (reconstructed the correct single character from context and replaced the corrupted blob via SQL, bypassing n8n-mcp entirely), and confirmed all of the above now succeed cleanly. So I can't hand you a live repro workflow, but a synthetic repro should be easy: create a Code node whose
jsCodecontains a long (~10K+ char) run of unusual/repeated non-ASCII bytes (e.g.'Ã'.repeat(10000)type content) inside a comment or string literal, and calln8n_get_workflowwithmode: "filtered"targeting just that node, orn8n_validate_workflowwith a single validation type. My guess is a regex somewhere (maybe a secret-scanner, sanitizer, or Unicode-normalization step) hitting catastrophic backtracking on the repeated pattern, or a response large/malformed enough to break the stdio framing without a caught error — I don't have server-side logs to confirm which.Impact
Both are core tools. Bug A makes
n8n_validate_workflow/n8n_update_partial_workflowunreliable enough that I stopped trusting a single "no crash" result as confirmation. Bug B forced a fallback to raw SQL againstworkflow_entityto fix a workflow at all, bypassingworkflow_history/versionIdbookkeeping (a separate but related footgun:n8n export:workflowwithout--published/--versionresolves throughversionId, not the livenodescolumn, so a SQL fix "disappears" from the CLI export until something else triggers a proper save).Happy to share more detail (the exact 9-node structure for Bug A, or help building a synthetic Bug B repro) if useful.