Challenge 2: Explain What Breaks a Bad Cache Key — Possible Solution ==================================================================== WHAT HAPPENS WHEN A DEPENDENCY IS ADDED -------------------------------------------- Since the cache key is the fixed string "npm-cache" — never changing regardless of what's actually inside package.json — adding a new dependency doesn't change the key at all. The next pipeline run looks for a cache entry matching "npm-cache", finds the SAME cache that was stored before the new dependency was added, and restores THAT old, now-outdated node_modules directory instead of running a fresh npm install that would actually fetch the newly added package. WHY THIS IS A PROBLEM ------------------------ The pipeline's node_modules directory now genuinely does NOT contain the newly added dependency — code that imports or requires that new package will fail at runtime (or during the test run itself) with a "module not found" style error, EVEN THOUGH package.json correctly lists it as a dependency. This directly matches this chapter's own warning: "a pipeline that passes using old, cached dependencies instead of the new ones a developer just added" — except in this specific case, it's actually likely to FAIL rather than silently pass, since the missing package would typically cause an immediate, visible error the moment something tries to use it. A subtler and arguably worse version of this same problem: if a dependency is UPDATED (not just added) — say, upgrading a package to fix a bug — the stale cache would keep restoring the OLD, buggy version of that package indefinitely, and the test suite might still pass using the outdated version, masking the fact that the actual, real dependency versions specified in the lockfile were never genuinely installed or tested at all. WHY THIS WORKS AS AN ANSWER ------------------------------ The root cause in both cases is identical: "nothing about the key itself changed to signal 'this cache is now invalid.'" A static string key has no relationship whatsoever to the actual CONTENTS of the lockfile, so the caching mechanism has no way to detect that anything has changed — it just keeps serving the same cached snapshot forever, regardless of how many times package.json/package-lock.json are actually modified. THE FIX -------- Use a cache key based on a HASH of the lockfile's contents (as this chapter's own example does via cache: 'npm' in actions/setup-node, which handles this correctly and automatically) — any change to package-lock.json produces a different hash, which produces a different cache key, which correctly causes a cache MISS and triggers a fresh, accurate npm install reflecting the lockfile's actual current state.