theonedev/onedev · error · UnauthorizedException
No package write permission for project:
Error message
No package write permission for project:
What it means
Thrown by checkProject when a write operation (npm publish or unpublish) is attempted by a user who lacks pack write permission on the project. It raises UnauthorizedException, which OneDev surfaces as HTTP 401 to the npm client.
Source
Thrown at server-plugin/server-plugin-pack-npm/src/main/java/io/onedev/server/plugin/pack/npm/NpmPackHandler.java:583
}
}
}
@Override
public String getApiKey(HttpServletRequest request) {
var authzHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
if (authzHeader != null&& authzHeader.toLowerCase().startsWith("bearer "))
return StringUtils.substringAfter(authzHeader, " ");
else
return null;
}
private Project checkProject(Long projectId, boolean needsToWrite) {
var project = projectService.load(projectId);
if (!project.isPackManagement())
throw new ClientException(SC_NOT_ACCEPTABLE, "Package management not enabled for project '" + project.getPath() + "'");
else if (needsToWrite && !SecurityUtils.canWritePack(project))
throw new UnauthorizedException("No package write permission for project: " + project.getPath());
else if (!needsToWrite && !SecurityUtils.canReadPack(project))
throw new UnauthorizedException("No package read permission for project: " + project.getPath());
return project;
}
@Override
public List<String> normalize(List<String> pathSegments) {
return pathSegments;
}
}
View on GitHub (pinned to d44925c47c)
Solutions
- Set a valid access token with package write permission in .npmrc: //onedev.example.com/:_authToken=<token>.
- Grant the user/job's role Pack Write (or higher) on the project in OneDev's authorization settings.
- Verify the Bearer token actually maps to an account with write access (test with a metadata GET first).
- Regenerate an expired token from User Profile -> Access Tokens and update .npmrc.
Example fix
// before (.npmrc) //onedev.example.com/:_authToken=<readonly-token> // after //onedev.example.com/:_authToken=<token-of-user-with-pack-write>
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check write access before publishing
const resp = await fetch(`${registryUrl}/${pkgName}`, { headers: { Authorization: `Bearer ${token}` } });
if (!resp.ok) throw new Error(`Registry auth failed: ${resp.status} — check token and Pack Write permission`); Try / catch
try {
await npmPublish();
} catch (e) {
if (String(e).includes('No package write permission') || e.code === 'E401') {
console.error('Publish unauthorized: use a token whose user has Pack Write on the project');
} else throw e;
} Prevention
- Provision CI tokens with Pack Write for publish pipelines.
- Rotate tokens before expiry and update .npmrc.
- Test publish access with a dry-run before releases.
When it happens
Trigger: PUT publish or DELETE unpublish where SecurityUtils.canWritePack(project) is false for the authenticated user — typically the account used in .npmrc is a job token or read-only user.
Common situations: Using a CI job secret token that only has read access; missing or expired access token in .npmrc (_authToken); user not added to the project with sufficient role; anonymous access configured instead of a credential.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- No package read permission for project:
- Not authorized
- Access denied
- Issue schedule permission required to set own estimated time
- Issue schedule permission required to set iterations
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/cbd5b3219eaf8159.
Report an issue: GitHub.