theonedev/onedev · error · UnauthorizedException
No permission to write code in issue project
Error message
No permission to write code in issue project
What it means
getIssueDetail throws UnauthorizedException with this message when the caller passes forWrite=true but the authenticated user cannot write code in the issue's project (SecurityUtils.canWriteCode fails). Write-oriented AI operations are restricted to users with commit/write access.
Source
Thrown at server-core/src/main/java/io/onedev/server/ai/TodResource.java:487
throw new NotFoundException("Issue not found: " + referenceString);
}
}
@Path("/get-issue")
@GET
public Map<String, Object> getIssueDetail(
@QueryParam("currentProject") @NotNull String currentProjectPath,
@QueryParam("reference") @NotNull String issueReference,
@QueryParam("forWrite") Boolean forWrite) {
var subject = SecurityUtils.getSubject();
if (SecurityUtils.getUser(subject) == null)
throw new UnauthenticatedException();
var currentProject = getProject(currentProjectPath);
var issue = getIssue(currentProject, issueReference);
if (forWrite != null && forWrite &&!SecurityUtils.canWriteCode(issue.getProject()))
throw new UnauthorizedException("No permission to write code in issue project");
return IssueHelper.getDetail(currentProject, issue);
}
@Path("/query-projects")
@GET
public List<Map<String, Object>> queryProjects(
@QueryParam("query") String query,
@QueryParam("offset") int offset,
@QueryParam("count") int count) {
var subject = SecurityUtils.getSubject();
if (SecurityUtils.getUser(subject) == null)
throw new UnauthenticatedException();
if (count > RestConstants.MAX_PAGE_SIZE)
throw new NotAcceptableException("Count should not be greater than " + RestConstants.MAX_PAGE_SIZE);
var parsedQuery = ProjectQuery.parse(query);View on GitHub (pinned to d44925c47c)
Solutions
- Call with forWrite=false (or omit) if only read access is needed.
- Grant the user (or token owner) a role with code-write permission in the issue's project.
- Use an access token from a user who is a committer/maintainer in that project.
Example fix
// before GET /api/tod/get-issue?currentProject=p&reference=p#1&forWrite=true // after (read-only) GET /api/tod/get-issue?currentProject=p&reference=p#1&forWrite=false
Defensive patterns
Strategy: validation
Validate before calling
// only request write when the user actually has code-write access
const forWrite = needsWrite && userCanWriteCode(issueProject, currentUser);
const params = { currentProject, reference, forWrite }; Try / catch
try {
return await getIssueDetail(params);
} catch (e) {
if (isUnauthorizedError(e) && /write code/.test(e.message)) {
return getIssueDetail({ ...params, forWrite: false });
}
throw e;
} Prevention
- Request forWrite=true only when the operation truly needs write access.
- Keep service tokens mapped to roles with the required write permissions.
- Audit role assignments when integrations start failing with permission errors.
When it happens
Trigger: Calling GET /get-issue with forWrite=true where the authenticated user's role in issue.getProject() lacks code-write permission.
Common situations: An AI agent requesting write access for a user who is only a reader; using a read-only CI/service token; user recently downgraded to a role without write access.
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 permission to access issue: ${referenceString}
- Code write permission is required to edit auto merge
- Not authorized
- Not authorized
- Access denied
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/c7759f89dbeea20b.
Report an issue: GitHub.