Summary
The NPM_TOKEN repository secret is rejected by the npm registry. The next commit to main that actually triggers a release (feat:, fix:, perf:, refactor:, revert:, docs(README):) will fail before publishing.
Evidence
Release run on main for #131 (run 31635670403):
[@semantic-release/npm] › ℹ Verifying OIDC context for publishing from GitHub Actions
[@semantic-release/npm] › ℹ OIDC token exchange with the npm registry failed: 404 OIDC token exchange error - package not found
[@semantic-release/npm] › ℹ Verify authentication for registry https://registry.npmjs.org/
npm error code E401
npm error 401 Unauthorized - GET https://registry.npmjs.org/-/whoami
✘ Failed step "verifyConditions" of plugin "@semantic-release/npm"
✘ EINVALIDNPMTOKEN Invalid npm token.
A 401 on /-/whoami is unambiguous — the token is expired, revoked, or malformed.
Why this has gone unnoticed
Every recent Release run reported success without ever validating the token, because semantic-release bails before verifyConditions when there is nothing to release. From the run immediately prior (31635364792):
ℹ The local branch main is behind the remote one, therefore a new version won't be published.
That run never reached the npm plugin. Same for the chore: / ci: commits before it — all green, none exercising the token. The last genuine publish was deride@2.2.0 (npm latest) back in April, when the token still worked.
So the green checkmarks on the release workflow are not evidence that releasing works.
Not caused by the semantic-release 25 upgrade
The upgrade in #129 is what surfaced this, but it is not the cause. The 401 comes from npm whoami against the registry — no semantic-release version affects that. The earlier runs simply exited before getting there.
Worth noting the log line above it: OIDC token exchange ... 404 - package not found. npm trusted publishing is not configured for this package, so the token path is the only path.
Fix
- Mint a new npm automation token with publish rights (and provenance, per CLAUDE.md) and replace the
NPM_TOKEN secret.
- Optionally, configure npm trusted publishing (OIDC) for
deride so the workflow stops depending on a long-lived token at all. @semantic-release/npm already attempts the OIDC exchange first, so this would need no workflow change — only registry-side configuration.
- Consider making the release dry-run actually exercise
verifyConditions, so an invalid token is caught on a PR rather than at release time.
Related
Summary
The
NPM_TOKENrepository secret is rejected by the npm registry. The next commit tomainthat actually triggers a release (feat:,fix:,perf:,refactor:,revert:,docs(README):) will fail before publishing.Evidence
Release run on
mainfor #131 (run 31635670403):A 401 on
/-/whoamiis unambiguous — the token is expired, revoked, or malformed.Why this has gone unnoticed
Every recent
Releaserun reported success without ever validating the token, because semantic-release bails beforeverifyConditionswhen there is nothing to release. From the run immediately prior (31635364792):That run never reached the npm plugin. Same for the
chore:/ci:commits before it — all green, none exercising the token. The last genuine publish wasderide@2.2.0(npmlatest) back in April, when the token still worked.So the green checkmarks on the release workflow are not evidence that releasing works.
Not caused by the semantic-release 25 upgrade
The upgrade in #129 is what surfaced this, but it is not the cause. The 401 comes from
npm whoamiagainst the registry — no semantic-release version affects that. The earlier runs simply exited before getting there.Worth noting the log line above it:
OIDC token exchange ... 404 - package not found. npm trusted publishing is not configured for this package, so the token path is the only path.Fix
NPM_TOKENsecret.derideso the workflow stops depending on a long-lived token at all.@semantic-release/npmalready attempts the OIDC exchange first, so this would need no workflow change — only registry-side configuration.verifyConditions, so an invalid token is caught on a PR rather than at release time.Related