Save NPM Cache always uploads artifact, even when cache is hit

I have a “Restore NPM Cache” step at the beginning of a workflow and “Save NPM Cache” at the end of the workflow. My yarn.lock file is in the root directory of the repo that is being cloned. The “Save NPM Cache” is always uploading an artifact even when it doesn’t need to, does anyone know how to avoid that unnecessary upload? It gives this reason:

Can’t skip uploading the cache, reason: there was no cache restore in the workflow with this key, but was for other(s)

The restore step’s log:


| (3) Restore NPM Cache                                                        |
+------------------------------------------------------------------------------+
| id: restore-npm-cache                                                        |
| version: 1.1.1                                                               |
| collection: https://github.com/bitrise-io/bitrise-steplib.git                |
| toolkit: go                                                                  |
| time: 2024-12-06T21:30:17Z                                                   |
+------------------------------------------------------------------------------+
|                                                                              |
 * [OK] Step dependency (zstd) installed, available.
Input:
- verbose: false
Cache keys:
{{ .OS }}-{{ .Arch }}-npm-cache-{{ checksum "package-lock.json" "yarn.lock" }}
{{ .OS }}-{{ .Arch }}-npm-cache-

Evaluating key template: {{ .OS }}-{{ .Arch }}-npm-cache-{{ checksum "package-lock.json" "yarn.lock" }}
Build trigger doesn't have an explicit git commit hash, using the Git Clone Step's output for the .CommitHash template variable (value: 47d061895d7e8599870a0c87f22dd43b02124349)
Cache key: darwin-arm64-npm-cache-d78a952fe633cb78d7f3bf4f26e54ead8b49a6c653401f7aa094fadcd8757cde

Evaluating key template: {{ .OS }}-{{ .Arch }}-npm-cache-
Build trigger doesn't have an explicit git commit hash, using the Git Clone Step's output for the .CommitHash template variable (value: 47d061895d7e8599870a0c87f22dd43b02124349)
Cache key: darwin-arm64-npm-cache-

Downloading archive...
Cache hit for key: darwin-arm64-npm-cache-562ac3b0672caddbc2b1d05da03318aaaf3ba04180b60e533926d08bd5735799
Archive size: 239MB
Downloaded archive in 12s
Restoring archive...
Restored archive in 18s

And the save step:


| (11) Save NPM Cache                                                          |
+------------------------------------------------------------------------------+
| id: save-npm-cache                                                           |
| version: 1.2.0                                                               |
| collection: https://github.com/bitrise-io/bitrise-steplib.git                |
| toolkit: go                                                                  |
| time: 2024-12-06T21:39:24Z                                                   |
+------------------------------------------------------------------------------+
|                                                                              |
 * [OK] Step dependency (zstd) installed, available.
Input:
- verbose: false
- compression_level: 3
Cache key: {{ .OS }}-{{ .Arch }}-npm-cache-{{ checksum "package-lock.json" "yarn.lock" }}
Cache paths:
node_modules

Evaluating key template: {{ .OS }}-{{ .Arch }}-npm-cache-{{ checksum "package-lock.json" "yarn.lock" }}

Build trigger doesn't have an explicit git commit hash, using the Git Clone Step's output for the .CommitHash template variable (value: 47d061895d7e8599870a0c87f22dd43b02124349)
Cache key: darwin-arm64-npm-cache-d78a952fe633cb78d7f3bf4f26e54ead8b49a6c653401f7aa094fadcd8757cde

Can't skip saving the cache, reason: there was no cache restore in the workflow with this key, but was for other(s)
Other restored cache keys:
darwin-arm64-npm-cache-562ac3b0672caddbc2b1d05da03318aaaf3ba04180b60e533926d08bd5735799

Creating archive...
Using installed zstd binary
Archive created in 1m32s
Archive size: 239MB

Can't skip uploading the cache, reason: there was no cache restore in the workflow with this key, but was for other(s)

Uploading archive...
Archive uploaded in 12s
|                                                                              |
+---+---------------------------------------------------------------+----------+
| ✓ | Save NPM Cache                                                | 1.8 min |
+---+---------------------------------------------------------------+----------+

Update: I ended up just using my own custom save + restore cache step for yarn since it was also not caching the global yarn cache folder which is where most packages were actually stored, which mean it was only caching a few of 3000+ packages. This is working as expected.

The “Restore Cache” config:
key: {{ .OS }}-{{ .Arch }}-yarn-{{checksum "yarn.lock"}}

The “Save Cache” config:
key: key: {{ .OS }}-{{ .Arch }}-yarn-{{checksum "yarn.lock"}}
paths:

node_modules/
.yarn/cache/

unique cache key: true