GitHub Actions Cache Misses Across OS - Missing runner.os in Key
A cache built on one OS or architecture is wrongly restored (or never matches) on another because the key omits runner.os/runner.arch. Native dependencies cached on Linux are not valid on Windows or macOS.
What this error means
In a multi-OS matrix, caches miss constantly, or worse, a restored cache contains binaries built for the wrong platform and the build fails in confusing ways.
key: deps-${{ hashFiles('package-lock.json') }}
# same key on ubuntu, windows, macos - native modules clashCommon causes
Key omits OS and architecture
A key derived only from a lockfile hash is shared across every runner. Platform-specific contents (native modules, compiled artifacts) do not transfer between OSes.
Matrix runs share one key
Without runner.os in the key, all matrix legs contend for the same cache entry, causing constant evictions or wrong-platform restores.
How to fix it
Include runner.os (and arch) in the key
Prefix the key with the OS and architecture so each platform gets its own cache.
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-${{ runner.arch }}-npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-npm-Scope restore-keys per platform too
- Make restore-keys start with the same runner.os/arch prefix.
- Avoid caching fully built native trees across OSes; cache the download cache instead.
- Verify each matrix leg restores its own platform cache.
How to prevent it
- Always prefix cache keys with runner.os (and runner.arch where relevant).
- Keep restore-keys platform-scoped to match.
- Cache package-manager downloads rather than platform-specific built trees.