Build1 publisher2 min readPublished
Three flipped defaults in n8n 2.0 can change a workflow nobody edited
A dev.to walkthrough of the n8n 1.x to 2.0 upgrade treats it as a host-configuration review, because the defaults that changed decide what Code nodes may read and which nodes exist at all.
The Engineer · Build desk

What happened
- ExecuteCommand and LocalFileTrigger ship disabled by default, with NODES_EXCLUDE as the configuration route back to them.
- The Pyodide-based Python Code implementation is removed, Python execution moves to the task-runner model, and Python Code nodes require task runners in external mode.
- $evaluateExpression no longer works inside the Code node as before, which n8n documents as a breaking change alongside a temporary insecure-mode workaround.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint Behaviour can change without a workflow edit, so change control that tracks workflow JSON will not show the diff that matters; the diff is in the host configuration.
- decision Teams that need shell or local-file triggers must now write that permission into NODES_EXCLUDE deliberately. A capability a 1.x instance had by default becomes a documented grant.
- cost Python users have the most work here: the interpreter is swapped, so every Python node needs retesting and external-mode runners need deploying before the version change.
- exposure Any instance that kept API keys in process.env and read them from Code nodes has a credential migration to do inside the upgrade window.
Each of the three default changes has its own setting, and that shapes how you rehearse the upgrade. Task runners are on by default, and Code node executions run on them [1]. Environment-variable access from the Code node is blocked by a second setting, `N8N_BLOCK_ENV_ACCESS_IN_NODE=true` [3]. Node availability is a third control, `NODES_EXCLUDE`, which is how n8n lets you re-enable ExecuteCommand and LocalFileTrigger when a workflow genuinely needs them [5].
The pre-flight advice in the write-up is to set `N8N_RUNNERS_ENABLED=true` on 1.x and test Code nodes there [2]. That rehearses one change of the three. A Code node that reads `process.env` passes that dry run and can stop working once the env block is in force [3]. Reproducing 2.0 behaviour on 1.x takes the runner flag, the env-access block, and an exclusion entry covering the two disabled nodes [14]. The suggested remedy is to stop using the Code node as a secret store and attach secrets to n8n credentials [4].
Python is a runtime replacement. n8n 2.0 removes the Pyodide-based Python Code implementation and moves Python execution to the task-runner model, and Python Code nodes require task runners in external mode [8]. The native implementation does not support the same built-in variables Pyodide provided, so code that references `_input` has to be reviewed [9]. External mode has to be deployed, so this part of the upgrade lands on whoever runs the n8n process.
`$evaluateExpression` no longer works inside the Code node as it did, and the post says n8n documents this as a breaking change [6]. An insecure-mode workaround exists, which the post describes as a temporary compatibility option and not the preferred production solution [7]. The post sets the migration test as a question: "Does my workflow still execute with the same inputs, permissions, side effects, and outputs?" [10]. Opening a workflow in the editor does not answer that.
This is one write-up. It names defaults changing around databases, OAuth, binary data and workflow publishing without itemising them, and it does not date the release [12]. The three changes it does itemise are narrow in scope: an instance with no Code nodes, no Python Code nodes, and neither ExecuteCommand nor LocalFileTrigger in use comes through all three unchanged [15].
What to watch
- Whether n8n's own migration documentation itemises the database, OAuth, binary data and workflow publishing default changes the write-up only names.
- Whether the insecure-mode compatibility option for $evaluateExpression gets a removal version attached to it.
- Whether a supported external-mode task-runner deployment recipe appears for self-hosters running Python Code nodes.