TEST REPORT: n8n 3.0 Upgrade Check v1.0.0
Run by N8N_BIN=n8n245/node_modules/.bin/n8n bash tests/run_all.sh; full output in tests/logs/run-20261030.txt.
Started 2026-10-30 09:10:13 GMT, finished 09:10:28 GMT (times from date at run time). Box: Linux, Python 3.13.5, npm 11.21.1, n8n 2.45.7 (npm, current latest/stable tag).
Result: 3/3 steps passed, FAILED STEPS: 0. 20/20 tests (15 scanner, 3 npm cross-checks with per-node subtests, 2 real-n8n round trip).
What is real and what is not
- Real: the shipped
scripts/n8n3_scan.pyrun as a module and as a CLI. Real npm packagesn8n-nodes-baseand@n8n/n8n-nodes-langchainat 2.45.6, 2.46.3 and 3.0.1 (npm pack, readingdist/types/nodes.json). A real n8n 2.45.7 CLI importing and exporting the fixture workflows into a throwaway SQLite user folder. - Not tested at first: n8n 3.0 itself (superseded: see "Real-app verification 2026-10-30" below, where workflows were run on a real n8n 3.0.1). 3.0 is Docker-only and Docker isn't available on the test box. The rules come from the official breaking-changes page (checked 30 Oct 2026) plus the npm node-list diff.
- Not tested: real customer exports, Kubernetes/Helm values, custom Dockerfiles, Windows paths, Python versions below 3.13 (the code uses only the standard library and targets 3.9+, but only 3.13.5 was run).
- Fixtures are hand-written and use real node type names and versions (checked against npm, below). Deployment fixtures (.env, docker-compose.yml, package.json) are made-up examples.
1. Scanner: tests/test_scan.py (15/15)
- All 9 removed node types in the fixture are found, with replacements; a removed trigger gets the "won't activate" note.
- Each workflow rule fires on its fixture node: AGENT-V1, EDIT-IMAGE-V1, SUBWORKFLOW-SOURCE, GETPAIREDITEM, EVALEXPR, SLACK-SIGNING-SECRET, GMAIL-TRIGGER, ALWAYS-OUTPUT, COMPRESSION-LIMITS, WEBFLOW-LEGACY, CHAT-WEBSOCKET, SSRF-CGNAT, COMMUNITY-NODES.
- A modern workflow (Schedule Trigger, HTTP Request 4.2, Set 3.4, AI Agent 3.1, Gmail Trigger 1.4, Edit Image 2, Execute Workflow from database) has 0 findings.
- Slack Trigger is a blocker when published (
activeoractiveVersionId) and a warning when not. - CGNAT boundaries: 100.64.0.1 and 100.127.255.254 flagged; 100.63.255.255, 100.128.0.1 and 10.0.0.5 not.
- Input formats: folder of
--separatefiles, CLI--allarray, public API{"data": [...]}; archived skipped unless--include-archived; broken JSON reported without stopping the scan. - Deployment: 1.x image -> FROM-1X;
package.jsondependency andn8n startscript -> 2 NPM-INSTALL; 3 removed env vars (a commented-out line is ignored); binary modedefault;.n8n/binaryDatavolume; missing task timeout; insecure-mode note; SSRF note. A clean 2.45.7 compose file gives 0 findings; a 2.20 image gives NO-MIGRATION-REPORT. - CLI exit codes: 1 with blockers, 0 clean, 2 for a missing path or only-broken input;
--strictturns warnings into exit 1;--jsonand--markdownoutput parse. - SKILL.md has valid frontmatter and explains every rule id used in the code.
2. Against npm: tests/test_against_npm.py (3/3)
- The scanner's removed-node list equals the npm diff exactly: 572 node types in 2.45.6, 535 in 3.0.1, 37 removed.
- Every node type and
typeVersionin the fixtures exists in real n8n 2.x packages. - The node types the rules target still exist in 3.0.1, Gmail Trigger 1.4 exists in 2.45.6, and Edit Image v2 is in 2.46.3 and 3.0.1 but not in 2.45.6.
3. Real n8n 2.45.7 round trip: tests/test_real_n8n.py (2/2)
n8n import:workflowof the unmodified fixtures is rejected by 2.45.7: "Cannot use a n8n-nodes-base.function node … this node type is deprecated". So current 2.x already refuses Function/Function Item on import (documented in the reference and the README for buyers restoring old backups).- With those 2 nodes removed, the fixtures import, export with
export:workflow --alland with--all --separate --pretty, and scanning either export gives the same findings as the input (13 blockers, 5 warnings, 2 notes). Slack Trigger is excluded from that comparison because CLI import unpublishes workflows, which correctly turns that blocker into a warning.
Failures seen during development (fixed before the logged run)
- First
test_scan.pyrun: 1 error,SKILL.mdnot written yet. Fixed by writing it. - First full run: 1 failure. The "clean" fixture used Edit Image v2, which doesn't exist in 2.45.6. Checking npm showed v2 first ships in 2.46.x (the npm
beta/nexttag on 30 Oct). This was a real finding: the fix text now says to move to 2.46+ before moving Edit Image to v2, and the test checks it.
Nothing was published, deployed or sent. The npm cache (tests/.npm-cache, ~38 MB; moved out of the draft folder after the run) is a download cache and should be left out of the zip.
Real-app verification 2026-10-30
Run by N8N_BIN=n8n245/node_modules/.bin/n8n N8N3_CMD="n8n3-run/start.sh N8N_RUNNERS_BROKER_PORT=5695" N8N3_HOST_DATA=n8n3-run/data N8N3_DATA=/data bash tests/run_all.sh. Full output is in tests/logs/run-20261030-realapp.txt. The run started at 12:12:40 GMT and finished at 12:13:33 GMT.
Result: 4/4 steps passed, FAILED STEPS: 0. 24/24 tests: 17 scanner, 3 npm, 2 real n8n 2.45.7 and 2 real n8n 3.0.1.
How 3.0.1 was run
- npm has no runnable n8n 3.x. The image
n8nio/n8n:3.0.1was pulled from Docker Hub with the registry API. Docker isn't installed, so its layers were unpacked to/opt/n8n3/rootfs. - The image's own Node 26.12.1 and
n8nCLI run in a chroot as uid 1000. Settings:N8N_USER_FOLDER=/data, SQLite, port 5690 on 127.0.0.1, andN8N_RELEASE_TYPE=rcas in the image. - This is the real 3.0.1 code, not a mock. It is not Docker's network or cgroup setup, and the Python task runner isn't available in this image (n8n logs "Python 3 is missing").
What was checked on real 3.0.1
- Import and export.
n8n import:workflow --separateimported all 4 unmodified fixtures, including Function, Cron and Item Lists: "Successfully imported 4 workflows". It deactivated "Clean modern" and "Legacy everything". - So 3.0.1 does not refuse removed nodes on import, unlike 2.45.7. They fail only when run. Don't count on an import error to catch them.
- The
export:workflow --alloutput scanned to the same findings as the input. - Execution probes (
tests/fixtures/probes-3x, run withn8n execute --id=…). There are 9 probes: an Execute Workflow Trigger, a Set node, and the node under test. The rule is that a probe runs if and only if the scanner reports no blocker for it. All 9 agreed:
| Probe | Real 3.0.1 result | Scanner |
|---|---|---|
Code node (x*21) |
ran, y: 42 |
no findings |
| Function | Unrecognized node type: n8n-nodes-base.function |
N3-NODE-REMOVED |
| Function Item | Unrecognized node type: n8n-nodes-base.functionItem |
N3-NODE-REMOVED |
| Item Lists 3.1 | Unrecognized node type: n8n-nodes-base.itemLists |
N3-NODE-REMOVED |
| HTML Extract | Unrecognized node type: n8n-nodes-base.htmlExtract |
N3-NODE-REMOVED |
Code with $evaluateExpression |
The function "$evaluateExpression" is not available in this context |
N3-EVALEXPR |
Set with $getPairedItem |
$getPairedItem was removed. Use $('Node').item, … |
N3-GETPAIREDITEM |
| Edit Image v1 | Edit Image versions 1 and 1.1 are no longer supported. Upgrade the node to version 2. |
N3-EDIT-IMAGE-V1 |
| Execute Workflow, source localFile | The "Local File" source was removed. … |
N3-SUBWORKFLOW-SOURCE |
- Node list. The real 3.0.1 install has 535 node types in n8n-nodes-base and nodes-langchain. None of the scanner's 37 removed types is present.
- n8n's own Migration Report rules. 3.0.1 ships them in
dist/modules/breaking-changes/rules/v3, 25 rule files. The scanner was compared with each one: - Their removed-node list (36, with AI Transform as its own rule) equals the scanner's 37.
- Every workflow-level official rule has a scanner rule.
- Instance-only rules the scanner can't see from files: Import from URL removed, external-secrets project-role default, Slack credential can't be saved without a signature secret. These are now listed in SKILL.md Limits and point to the Migration Report.
Bugs found and fixed
- N3-AGENT-V1 gave the wrong mode and severity. It labelled an AI Agent with no explicit mode as "toolsAgent (default)", and flagged every v<2 agent as a blocker.
- n8n 3.0.1's own rule (
agent-node-mode.js) treats no mode as Conversational Agent up to v1.5 and Tools Agent from v1.6. Only the Conversational, OpenAI Functions, Plan and Execute, ReAct and SQL modes fail. A v1.6–1.9 Tools Agent "will run with version 2 behavior" (a warning). - Fixed to match, with a new test
test_agent_mode_resolution_matches_n8n_301. - Missing: Chat hub off by default. This is in the official notes and in 3.0.1's
chat-hub-deprecatedrule. Added N3-CHAT-HUB (note) for when a deployment is checked andN8N_ENABLED_MODULESlackschat-hub. The tests were updated: a clean deploy now gives exactly this note, and listingchat-hubgives 0. - Missing: both storage directories exist, so 3.0 fails to start. This is in the official notes and in
storage-path-rename.rule.js. Added N3-STORAGE-BOTH (blocker) for a.n8nfolder under--deploycontaining bothbinaryDataandstorage. N3-STORAGE-PATH and N3-STORAGE-BOTH are now skipped whenN8N_STORAGE_PATHorN8N_BINARY_DATA_STORAGE_PATHis set, as in n8n's rule. New test:test_storage_both_dirs. - SKILL.md said N3-NO-MIGRATION-REPORT was a warning. The code emits a note; the doc was fixed. The rule count is now 25: 11 blockers, 9 warnings, 5 notes (README and LISTING updated).
test_against_npm.pycrashed withTimeoutExpiredon a fresh cache: npm wrote the tarball but didn't exit within 300 s. It now uses the tarball if it is complete, otherwise it skips.
Official 3.0 notes vs this pack (docs.n8n.io/changelog/v30-breaking-changes, fetched 2026-10-30)
- Covered: removed nodes, AI Agent < 2, Edit Image < 2, sub-workflow sources,
$getPairedItem,$evaluateExpression, Slack signing secret, Gmail Trigger 1.4, Always Output Data, compression limits, Webflow legacy, chat WebSocket JSON, SSRF ranges, removed env vars, binary data mode, task-runner timeout, unverified community packages, storage rename, Docker-only, 1.x to 3.x path. Chat hub and both-directories were added today. - Not covered, and needing no file-level action: encryption-key rotation on by default, the Ask AI tab removed, community-node
defaults.colorandn8n-nodedev-tool changes (node authors only). - The docs call 3.0 early access; the image is tagged
rc.
Still not tested: a real Docker or Kubernetes deployment, the Migration Report UI and REST endpoint (not run here; its rule code was read), real customer exports.
Re-run 2026-11-02 (promoted from drafts/2026-10-30 to products/)
N8N_BIN=n8n245/node_modules/.bin/n8n N8N3_CMD="n8n3-run/start.sh N8N_RUNNERS_BROKER_PORT=5695" … bash tests/run_all.sh; full output in tests/logs/run-20261102.txt, started 2026-11-02 07:13:46 GMT, finished 07:14:58 GMT.
Result: FAILED STEPS: 0, 24/24 tests: 17 scanner, 3 npm cross-checks, 2 real n8n 2.45.7, 2 real n8n 3.0.1 (chroot of the official 3.0.1 image, as above).
Extra finding on 3.0.1 (from the Stripe Access Drift Check tests, same day): on a never-started 3.x instance n8n import:credentials fails with "No active encryption key found"; 3.x creates the key on the first n8n start (dist/encryption/encryption-bootstrap.service.js, main instance only). Worth adding as a NOTE rule in v1.1 (not added yet; the scanner is unchanged).
Pre-launch re-run 2026-11-02
Same command as above, with real n8n 2.45.7 and the real n8n 3.0.1 chroot; full output in tests/logs/run-20261102-prelaunch.txt, started 08:00:30 GMT, finished 08:01:35 GMT. FAILED STEPS: 0, 24/24 tests (17 scanner, 3 npm, 2 real n8n 2.45.7, 2 real n8n 3.0.1). Counts unchanged. Box-specific install paths in the run commands above were shortened (e.g. n8n245/..., n8n3-run/...); the commands are otherwise as run.