Skip to content
Latchkey

Backstage "requires Node.js version" mismatch in CI

Backstage supports only active and maintenance LTS Node versions (currently Node 20 and 22). When CI runs an unsupported Node, the CLI or the engines check in package.json refuses to proceed.

What this error means

yarn or the backstage-cli aborts with "error @backstage/cli@...: The engine \"node\" is incompatible with this module. Expected version \"18 || 20 || 22\"." or a startup warning that the Node version is unsupported.

yarn
error @backstage/cli@0.29.0: The engine "node" is incompatible with this module.
Expected version "18 || 20 || 22". Got "23.2.0"
error Found incompatible module.

Common causes

The runner defaults to an unsupported Node

The CI image ships an odd or too-new Node (for example 23.x or an old 16.x) that Backstage does not list in its engines range.

No explicit Node pin in the workflow

Without actions/setup-node the job uses whatever Node the image happens to have, which drifts over time.

How to fix it

Pin a supported LTS Node with setup-node

  1. Add actions/setup-node with a supported LTS version.
  2. Place it before install and build steps.
  3. Match the version to the one in your Backstage engines field.
.github/workflows/ci.yml
- uses: actions/setup-node@v4
  with:
    node-version: 20

Read the supported range from package.json

Check the root engines.node value and align CI to it so local, CI, and container builds all agree.

package.json
"engines": {
  "node": "18 || 20 || 22"
}

How to prevent it

  • Pin an explicit LTS Node in every workflow with setup-node.
  • Keep engines.node in package.json aligned with what CI installs.
  • Avoid non-LTS (odd) Node versions for Backstage builds.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →