GitHub Actions hashFiles glob matches nothing and produces an empty cache key
hashFiles(pattern) returns a hash of the matched files, or an empty string when nothing matches. An empty hash collapses a cache key like deps-${{ hashFiles(...) }} into deps-, which never restores the intended cache and may collide.
What this error means
The cache never hits and the resolved key is just the static prefix with an empty hash segment.
github-actions
key: deps-${{ hashFiles('**/package-lock.json') }}
# package-lock.json is missing -> hashFiles returns '' -> key resolves to 'deps-'Common causes
Lockfile path does not exist
A wrong glob or a repo without the lockfile makes hashFiles match nothing and return empty.
Checkout did not include the file
A sparse or filtered checkout can exclude the file the glob expects.
How to fix it
Point hashFiles at a file that exists
- Verify the glob matches at least one tracked file in the repo.
- List candidate files in a debug step to confirm the path.
.github/workflows/ci.yml
key: deps-${{ runner.os }}-${{ hashFiles('package-lock.json', 'yarn.lock') }}Fail fast when the hash is empty
- Add a guard step that errors if hashFiles returns an empty string.
- This surfaces a missing lockfile instead of silently caching nothing.
How to prevent it
- Confirm the lockfile path before basing a cache key on it.
- Include runner.os and a static prefix so an empty hash is obvious.
Related guides
GitHub Actions hashFiles Returns Empty - Cache Key Has No HashFix GitHub Actions hashFiles() returning an empty string - the glob matched no files, so the cache key collap…
GitHub Actions Cache Never Hits - Key Changes Every RunFix an actions/cache that never restores because the key is non-deterministic - hashing a generated file, the…
GitHub Actions Cache Key Collision Across Branches Restores Wrong CacheFix GitHub Actions caches bleeding across branches - a key without a branch or lockfile component lets one br…