Skip to content

2.6.0 pre-push validation blocks workflows the instance accepts; workflows over 50 nodes are never instance-validated #664

Description

@tmdrtmdr

Summary

On n8nac 2.6.0, n8nac push runs runPrePushValidation and aborts on any finding. On our estate that blocks pushes of workflows the instance itself accepts, and for workflows over 50 nodes the instance check never runs at all.

Measured over all 231 of our tracked workflows (every one live and working): 93 are blocked by the bundled check alone. Instance is n8n 2.37.10, self-hosted.

Four separate problems. Each repro below is a minimal synthetic workflow, checked by calling PreflightNodeValidator from n8nac@2.6.0 directly: once with no endpoint (bundled), once with the instance endpoint (level ≥ 2). That is the class runPrePushValidation uses.

1. The bundled check blocks nodes the instance validator accepts

The bundled path is described as running "the server-equivalent gating rules". For these nodes it reports errors, and the instance's own validate_node_config returns valid: true for the same payload:

Node Bundled result Instance validate_node_config
n8n-nodes-base.if v1 with conditions.string[] Missing required parameter: "nodes[IF].parameters.conditions.options" valid
n8n-nodes-base.slack v2.2, resource/operation omitted (defaults) Field "parameters.select": This field is only allowed when one of: (resource="message", operation="post", ...) (same for channelId, text) valid
{ "name": "IF", "type": "n8n-nodes-base.if", "typeVersion": 1,
  "parameters": { "conditions": { "string": [ { "value1": "={{ $json.status }}", "value2": "paid" } ] } } }

{ "name": "Slack", "type": "n8n-nodes-base.slack", "typeVersion": 2.2,
  "parameters": { "select": "channel", "channelId": { "__rl": true, "value": "C0000000000", "mode": "id" },
                  "text": "hello", "otherOptions": {} } }

Two causes, as far as I can tell:

  • typeVersion is not respected for IF / Filter v1. conditions.options only exists from v2. 119 of our nodes are IF v1 or Filter v1. This is the legacy-version class left out of skills validate: multiOptions values, @version-scoped properties and defaulted required params reported as errors #609, but it now blocks a push instead of printing a hint.
  • Omitted default values are not applied before gating. n8n does not store a parameter that equals its default, so a Slack "post message" node has no resource/operation in its JSON. The gate then treats text/channelId as not allowed. About 100 of our nodes hit this, across Slack v1–v2.4, Telegram v1.1/v1.2, Google Drive v3, Merge v2.1, Gmail v2.1 and OpenAI v1.4. We also checked Slack v1, Filter v1, Google Drive v3 and Telegram v1.1 nodes from our workflows against the instance: all valid.

2. Bundled node versions are behind the instance

{ "name": "Tool", "type": "@n8n/n8n-nodes-langchain.toolWorkflow", "typeVersion": 2.2,
  "parameters": { "description": "demo", "workflowId": { "__rl": true, "value": "abc", "mode": "id" },
                  "workflowInputs": { "mappingMode": "defineBelow", "value": {}, "matchingColumns": [], "schema": [],
                                      "attemptToConvertTypes": false, "convertFieldsToString": false } } }

Bundled: typeVersion 2.2 does not exist for node "@n8n/n8n-nodes-langchain.toolWorkflow". Valid versions: [1, 1.1, 1.2, 1.3]. Use 1.3 (latest).
Instance: valid, and get_node_types on the instance returns the v2.2 definition. n8n-nodes-technical.json in skills 2.4.0 lists only [1, 1.1, 1.2, 1.3]. 38 of our nodes are on 2.x, and "Use 1.3" is not a safe fix: it changes the parameter shape.

3. Workflows with more than 50 nodes are never validated by the instance

validate_node_config on the instance rejects more than 50 nodes per call:

Input validation error: Invalid arguments for tool validate_node_config: nodes: Array must contain at most 50 element(s)

callServerValidate() (dist/core/services/preflight-node-validator.js) sends every node in one call. It then runs JSON.parse on that error text, which throws Unexpected token 'I', "Input vali"... is not valid JSON, and validateFile() falls back to the bundled check. A workflow of a trigger + 51 noOp nodes shows it: source: 'local', serverUnavailableReason: Unexpected token 'I' .... So on large workflows the authoritative check silently never runs, and the printed reason doesn't point at the cause. Batching in chunks of 50, and checking isError before parsing, would fix both.

4. Existing native-MCP users get the strictest level without opting in

effectiveNativeMcpLevel() (dist/services/config-service.js) ends with return nativeMcp.enabled || nativeMcp.url ? 3 : 0;. An environment configured before 2.6.0 (nativeMcp: { enabled: true, url, mode: "assist" }, no level) therefore validates live on every push after upgrading. I couldn't find a note on that behaviour change in the release notes. The only way out is N8NAC_PUSH_SKIP_VALIDATION=1, which also switches the check off for new workflows, where it is genuinely useful.

Related: the instance validator itself isn't a safe hard gate either. It rejects Baserow nodes with numeric databaseId/tableId (Type mismatches: "parameters.databaseId" (expected string, got number)) and accepts "1". Numbers are what the node's getDatabaseIds/getTableIds load-options return, so that is what the editor stores and what runs. That part is n8n core's validator, not n8nac, but it means blocking on the instance's answer alone would also stop working workflows (88 of our 231 have a Baserow node).

Suggestion

  • Block only on findings the instance confirms. Treat bundled-only findings as warnings until the bundled rules apply @version scoping and defaults.
  • Chunk validate_node_config calls to ≤ 50 nodes and handle isError results.
  • Make the blocking gate opt-in for environments configured before 2.6.0, or at least call it out in the release notes.

Happy to test a pre-release against our workflows. The measurement script runs read-only over a whole workspace.

Environment

  • n8nac 2.6.0 / @n8n-as-code/transformer 2.0.1 / @n8n-as-code/skills 2.4.0 / @n8n-as-code/mcp 2.2.0
  • n8n 2.37.10 (self-hosted, queue mode)
  • Windows 11, Node 26.5.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions