Skip to main content

Troubleshooting

Known problems with npm trusted publishing, GitHub Actions, Vercel and the GitHub CLI, and their fixes.

Start from the first failing job and step. Later failures are often only consequences. Fix one thing, re-run, repeat.

npm trusted publishing

E403 or "OIDC permission denied" on publish. The run does not match the trusted publisher. All of these must match exactly:

  • repository OWNER/REPO (a renamed or transferred repository does not match);
  • workflow file name, release.yml (a record for publish.yml does not authorize release.yml);
  • environment npm;
  • the job has permissions: id-token: write.

Check the record with npm trust list @lupinum/PACKAGE, fix it on npmjs.com, then Re-run failed jobs.

E404 from npm trust github. The package does not exist yet. Follow the first publication steps.

E409 from npm trust github. A record exists already. List it before you revoke anything.

ENEEDAUTH with no token configured. The npm CLI is too old for trusted publishing (it needs npm 11.5.1 or later). Use Node.js 24, which ships a new enough npm. Do not add a token.

The version is not visible right after publishing. npm scans new versions before serving them; this can take several minutes. It is not a failed publish.

latest points at an old version. npm never removes latest, and before a package has a stable version it can sit on an old prerelease. The first stable release moves it. Until then, or to repair it, the maintainer can re-point it with 2FA:

bash
npm dist-tag add @lupinum/example@1.0.0-rc.2 latest

next still points at a prerelease after the stable release. Remove it with npm dist-tag rm @lupinum/example next, or point it at the stable version. See Prereleases.

GitHub Actions

"Unable to resolve action" or "An action could not be found at the URI". The pinned SHA does not exist in that action's repository, or the path is wrong. Resolve the tag to its full 40-character SHA on the action's own repository and keep the version comment:

yaml
- uses: actions/checkout@<full 40-character sha> # v6

Never shorten a SHA or copy one from another action. Renovate keeps pins current.

CI does not run on the Version packages pull request. Pull requests created with the workflow's GITHUB_TOKEN do not trigger other workflows, so the required ci check never appears. release.yml starts ci.yml for that branch with workflow_dispatch, which is allowed. If the check is still missing, close and reopen the pull request; a human action triggers CI.

The Version packages pull request stays blocked while its ci run waits for approval. The pull_request run of ci.yml waits ("action_required") because a workflow pushed the branch, even when the run release.yml started has passed. Open it under Actions and approve it. This runs only the tests; it is not the npm approval.

Actions cannot create the Version packages pull request. Enable Allow GitHub Actions to create and approve pull requests; see Set up a repository.

The publish job waits and nobody can approve. The job must declare environment: npm, the environment must allow main, and the approver must be a required reviewer. With Prevent self-review on, the person who merged cannot approve; the standard turns it off.

The publish job of a new run never asks for approval. An older release run still waits for its npm approval and holds the publish slot. Cancel the older run (it packed older code); the new run then waits for approval.

A fixed workflow still fails on re-run. A re-run uses the workflow file of the original run. Merge the fix and start a new run.

Waiting for a runner. GitHub-hosted runner capacity. Wait, and check githubstatus.com if it takes long.

pnpm 11 fails in a Node.js 20 test lane. pnpm 11 needs Node.js 22 or later. Keep pnpm 11 and use the standalone mode of pnpm/action-setup, so pnpm runs on its own runtime while the tests run on Node.js 20. Do not downgrade pnpm; an older pnpm can ignore the quarantine settings.

Changesets

The next changelog repeats changes that were already released. The library is in a prerelease and .changeset/pre.json still lists released changesets in a changesets array, the Changesets 2 format. Changesets 3 ignores that list and treats released changesets as new. Move the listed files into .changeset/pre/, reduce pre.json to mode and tag, and check with pnpm changeset version in a scratch copy.

CI fails on the generated CHANGELOG.md in the Version packages pull request. A formatter that checks Markdown rejects what Changesets writes. Ignore **/CHANGELOG.md in the formatter; the version job runs no formatter.

release.yml offered a release while changesets were pending. The repository has an older copy of release.yml, where a skipped step's empty output compared equal to '0'. Copy the current release.yml from the starter, and cancel the offered run.

Build

"Potential missing package.json files: dist/agent/AGENTS.md". unbuild and the Nuxt Module Builder check the exports before scripts/agent-docs.mjs writes the agent docs. Copy the build:done hook from the nuxt-module starter's build.config.ts; it drops exactly this warning.

The packed package has no dist/agent/. The packing step rebuilt the package without the docs. Pack the output of pnpm build, which writes the agent docs last.

Renovate

No Renovate pull requests and no Dependency Dashboard issue. The Mend-hosted app is in Silent mode, which it uses by default when it is installed for all repositories of an organization. Open developer.mend.io, select the organization, check a repository's Recent jobs for dryRun=lookup, and turn Silent mode off under Settings → Dependency Updates. Renovate then runs on its schedule; the first run can take a few hours.

Vercel

A workspace package is missing during the docs build. Root Directory must be docs and Include files outside the Root Directory in the Build Step must be on. The build command in docs/vercel.json runs the root docs:build, which builds only the docs site, so the site must not import the library's built output. Test from a clean checkout.

Every push builds, or nothing builds. The ignoreCommand in docs/vercel.json exits 0 to skip and 1 to build. It compares VERCEL_GIT_PREVIOUS_SHA (the last successful deployment of the branch) with HEAD for the paths that feed the site, and builds when there is no usable previous SHA, for example on the first push of a branch:

sh
[ -n "$VERCEL_GIT_PREVIOUS_SHA" ] && git diff --quiet "$VERCEL_GIT_PREVIOUS_SHA" HEAD -- . ../package.json ../pnpm-lock.yaml ../pnpm-workspace.yaml || exit 1

Do not compare with HEAD^; that misses earlier commits in the same push. Vercel limits the command to 256 characters.

Pages load but navigation or search is broken. The HTML references /_nuxt/ files that are missing, usually from stale build output. Delete docs/.output and docs/.nuxt, then build again.

The domain shows an old version after a green build. Check which deployment is assigned to the production domain and the DNS. To roll back, promote the last good deployment in Vercel.

Corepack or pnpm version errors. Vercel reads packageManager from package.json. Set ENABLE_EXPERIMENTAL_COREPACK=1 in the project only if Vercel still uses the wrong pnpm.

GitHub CLI authentication

A failing gh auth status inside an agent sandbox does not mean the login expired; the sandbox often cannot reach the macOS keychain or the network. Re-run with the sandbox's approved elevated access:

bash
gh auth status -h github.com
gh api user --jq .login

Ask for a new login only if that fails with a real authentication error. Never copy a token into GH_TOKEN, a file or a secret to work around the keychain.