GitHub Packages "permission_denied: write_package" in CI
GitHub Packages rejected the publish because the token had no write permission for packages. The default GITHUB_TOKEN needs permissions: packages: write, and the package must be linked to a repository the token can write.
What this error means
A publish to GitHub Packages fails with "permission_denied: write_package", or npm reports "403 Forbidden - PUT https://npm.pkg.github.com/@owner%2fpkg - permission_denied: write_package".
npm error code E403
npm error 403 Forbidden - PUT https://npm.pkg.github.com/@owner/pkg - permission_denied: write_package
npm error 403 In most cases, you or one of your dependencies are requestingCommon causes
The job does not grant packages: write
GITHUB_TOKEN defaults to limited scopes. Without permissions: packages: write on the job or workflow, the publish has no write access.
The package is not linked to a writable repo, or scope mismatch
Publishing under a scope/owner the token cannot write to, or to a package not connected to the workflow repository, returns permission_denied.
How to fix it
Grant packages: write to the job
Add the permission and authenticate npm to the GitHub Packages registry with GITHUB_TOKEN.
permissions:
contents: read
packages: write
jobs:
publish:
steps:
- uses: actions/setup-node@v4
with:
registry-url: 'https://npm.pkg.github.com'
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}Match the scope to the repository owner
GitHub Packages scopes packages to an owner. Ensure package.json name uses @owner/... and the publishConfig registry points at GitHub Packages.
{
"name": "@owner/pkg",
"publishConfig": { "registry": "https://npm.pkg.github.com" }
}How to prevent it
- Add
packages: writeto any job that publishes to GitHub Packages. - Scope the package name to the repository owner.
- Use GITHUB_TOKEN for same-repo publishes; a PAT for cross-repo writes.