GitHub Actions "npm publish 403 to GitHub Packages" (scope)
Publishing an npm package to GitHub Packages requires the package name to be scoped to the owner, the registry configured to npm.pkg.github.com, and packages: write on the token. A scope or registry mismatch yields a 403.
What this error means
npm publish returns a 403 forbidden against npm.pkg.github.com even though authentication appeared to succeed.
npm error code E403
npm error 403 Forbidden - PUT https://npm.pkg.github.com/@owner%2fpkg - permission_deniedCommon causes
Package not scoped to the owner
GitHub Packages requires @owner/name scoping that matches the repository owner.
Missing packages: write or registry config
The job lacks packages: write, or .npmrc/setup-node did not point the scope at npm.pkg.github.com.
How to fix it
Fix scope, registry, and permission
- Scope the package name as @owner/name in package.json.
- Configure setup-node with the registry and scope, and grant packages: write.
- Authenticate with NODE_AUTH_TOKEN set to GITHUB_TOKEN.
publish:
permissions:
packages: write
contents: read
steps:
- uses: actions/setup-node@v4
with:
registry-url: https://npm.pkg.github.com
scope: '@owner'
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}How to prevent it
- Keep the package scope aligned with the repository owner.
- Configure the registry-url and scope via setup-node so .npmrc auth is generated correctly.