DEV Community

Kashif Manzer
Kashif Manzer

Posted on

GitHub Deleted Node 20 From Actions Runners: The 15-Minute Triage Checklist

On September 23, 2026, GitHub removed the Node.js 20 runtime from Actions runners. Any JavaScript action whose action.yml still declares runs.using: node20 can no longer start: the job fails at action startup, before your tests even run.

Timeline (from the official changelog):

  • 2025-09-19: deprecation announced
  • 2026-06-16: node20 actions force-run on Node 24 with a warning
  • 2026-09-23: Node 20 removed entirely (revised up from Sept 16)

If your CI went red yesterday and you haven't touched anything: this is why. Here's how to triage it in 15 minutes.

Check 1: Confirm you're hit (1 min)

Open your latest workflow run logs and search for: Node.js 20 actions are deprecated

Hit = your pins are stale.

Check 2: Inventory every action pin (5 min)

grep -rhoE 'uses:[[:space:]]*[^[:space:]#]+' .github/workflows/*.yml .github/actions/*/action.yml 2>/dev/null | sort -u
Enter fullscreen mode Exit fullscreen mode

Note the second path: composite actions live in .github/actions/ and are invisible to Dependabot-style tag scans. You must grep them separately.

Check 3: Resolve each pin's actual runtime (5 min)

Do not trust tag names. The node24 boundary is not uniform across majors: upload-artifact only moved to node24 at v6, download-artifact at v7. For each third-party pin:

gh api 'repos/<owner>/<repo>/contents/action.yml?ref=<ref>' --jq '.content' | base64 -d | grep -A1 '^runs:'
Enter fullscreen mode Exit fullscreen mode

using: node20 = broken. using: node24 = safe. using: composite or using: docker = unaffected.

Check 4: Self-hosted runners: check the floor (2 min)

node24 actions require runner >= 2.327.1. Below that, bumped actions fail even with correct pins. Also: Node 24 doesn't run on macOS <= 13.4 or ARM32 at all: those jobs need a different plan.

The bumps everyone hits

Action Broken pin Minimal node24 major Watch out
actions/checkout v4 v5 v6 moves credentials out of .git/config; v7 blocks fork-PR checkout by default
actions/setup-node v4 v5 v5 enables package-manager caching by default: disable with package-manager-cache: false in privileged workflows
actions/setup-python v5 v6 Clean bump, runtime only
actions/setup-go v5 v6 v6 honors the toolchain directive and defaults GOTOOLCHAIN=local: use go-version-file: 'go.mod' or builds break
actions/upload-artifact v4 v6 Do NOT stop at v5: it still runs node20 by default
actions/download-artifact v4 v7 v5 changed single-artifact download paths; pair with upload v6

Prefer the minimal node24 major: each extra major crossed is unrelated breaking change you absorb for nothing.

The two gotchas that bite backend repos hardest

setup-go@v6 silently changes which Go you build with. v6 honors the toolchain directive in go.mod (v5 ignored it) and defaults GOTOOLCHAIN=local, which forbids the silent toolchain downloads v5 allowed. If your workflow pins go-version: 1.24 but go.mod says go 1.25, builds fail. Fix: go-version-file: 'go.mod'.

There is no rollback to node20. The runtime is gone: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 and friends do nothing now. "Rollback" means retreating to a different node24 major, never back to the old pin.


I spent today turning this into a complete one-afternoon migration kit: all 19 actions in the pin-bump map with landmines, the ordered 7-step migration, 6 code-review prompts, a testing/verification plan, the honest rollback plan, and every gotcha above sourced. It's $39 here: https://kmanzer.gumroad.com/l/sreej

Every version number in it was verified against upstream release notes or real migration reports on the build date. Good luck out there: and check your composite actions.

Top comments (0)