theonedev/onedev · error · UnauthorizedException
Issue schedule permission required to set iterations
Error message
Issue schedule permission required to set iterations
What it means
OneDev's AI tod resource throws UnauthorizedException when an agent attempts to set an issue's 'iterations' field via editIssue without the 'Schedule Issues' permission on the issue's project. The check runs via SecurityUtils.canScheduleIssues before any iteration lookup happens, so the request is rejected outright.
Source
Thrown at server-core/src/main/java/io/onedev/server/ai/TodResource.java:636
issueChangeService.changeConfidential(user, issue, confidential);
}
Integer ownEstimatedTime = (Integer) data.remove("ownEstimatedTime");
if (ownEstimatedTime != null) {
if (!subscriptionService.isSubscriptionActive())
throw new NotAcceptableException("An active subscription is required for this feature");
if (!issue.getProject().isTimeTracking())
throw new NotAcceptableException("Time tracking needs to be enabled for the project");
if (!SecurityUtils.canScheduleIssues(subject, issue.getProject()))
throw new UnauthorizedException("Issue schedule permission required to set own estimated time");
issueChangeService.changeOwnEstimatedTime(user, issue, ownEstimatedTime*60);
}
@SuppressWarnings("unchecked")
List<String> iterationNames = (List<String>) data.remove("iterations");
if (iterationNames != null) {
if (!SecurityUtils.canScheduleIssues(subject, issue.getProject()))
throw new UnauthorizedException("Issue schedule permission required to set iterations");
var iterations = new ArrayList<Iteration>();
for (var iterationName : iterationNames) {
var iteration = iterationService.findInHierarchy(issue.getProject(), iterationName);
if (iteration == null)
throw new NotFoundException("Iteration '" + iterationName + "' not found");
iterations.add(iteration);
}
issueChangeService.changeIterations(user, issue, iterations);
}
if (!data.isEmpty()) {
if (!SecurityUtils.canEditIssueFields(subject, issue))
throw new UnauthorizedException("No permission to update issue fields");
issueChangeService.changeFields(user, issue, FieldUtils.getFieldValues(subject, issue.getProject(), data));
}
return IssueHelper.getDetail(currentProject, issue);View on GitHub (pinned to d44925c47c)
Solutions
- Grant the user (or their group) the 'Schedule Issues' permission in the project's or organization's role settings.
- Use an authenticated identity that has scheduling rights on the project.
- Remove the 'iterations' key from the request data and change iterations through the regular UI/API with a permitted account.
Example fix
// before (client sends iterations as underprivileged user)
data.put("iterations", List.of("Sprint 1"));
// after: authenticate as a user with Schedule Issues permission, or drop the key
if (SecurityUtils.canScheduleIssues(subject, project)) {
data.put("iterations", List.of("Sprint 1"));
} Defensive patterns
Strategy: try-catch
Validate before calling
// client-side check before calling editIssue with 'iterations'
if (!userPermissions.includes("Schedule Issues")) {
throw new Error("Skipping iterations update: schedule permission missing");
} Type guard
function canSchedule(user, project) {
return Boolean(user?.projects?.[project]?.permissions?.includes("Schedule Issues"));
} Try / catch
try {
await editIssue(project, ref, { iterations: ["Sprint 1"] });
} catch (e) {
if (e.status === 401 || /schedule permission/i.test(e.message)) {
// fall back to a permitted identity or skip iteration changes
} else throw e;
} Prevention
- Check the user's effective project permissions before planning iteration changes.
- Keep AI agent identities in groups that include Schedule Issues when iteration management is intended.
- Audit role settings after project permission changes.
When it happens
Trigger: Calling the AI tod editIssue endpoint (TodResource.editIssue) with an 'iterations' key in the data map while the authenticated subject lacks issue schedule permission on the target project.
Common situations: AI agent acting as a user who can edit issue fields but not manage schedules; project where only project owners/managers have Schedule Issues; permission recently revoked from the user.
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 update issue fields
- No permission to add specified link for specified issues
- No permission to access issue:
- No permission to read code of source project:
- No permission to read code of target project:
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/fd700f9bd5b7f45d.
Report an issue: GitHub.