theonedev/onedev · error · UnauthorizedException
Issue schedule permission required to set iterations
Error message
Issue schedule permission required to set iterations
What it means
The setIterations endpoint (POST /api/issues/{issueId}/iterations) requires issue schedule permission in the issue's project. If SecurityUtils.canScheduleIssues(subject, project) fails, UnauthorizedException (HTTP 401) is thrown before any iteration validation.
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/IssueResource.java:424
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(issue.getProject()))
throw new UnauthorizedException("Issue schedule permission required to set own estimated time");
issueChangeService.changeOwnEstimatedTime(user, issue, minutes);
return Response.ok().build();
}
@Api(order=1300, description="Schedule issue into specified iterations with list of iteration id")
@Path("/{issueId}/iterations")
@POST
public Response setIterations(@PathParam("issueId") Long issueId, List<Long> iterationIds) {
Issue issue = issueService.load(issueId);
var subject = SecurityUtils.getSubject();
var user = SecurityUtils.getUser(subject);
if (!SecurityUtils.canScheduleIssues(subject, issue.getProject()))
throw new UnauthorizedException("Issue schedule permission required to set iterations");
Collection<Iteration> iterations = new HashSet<>();
for (Long iterationId: iterationIds) {
Iteration iteration = iterationService.load(iterationId);
if (!iteration.getProject().isSelfOrAncestorOf(issue.getProject()))
throw new NotAcceptableException("Iteration is not defined in project hierarchy of the issue");
iterations.add(iteration);
}
issueChangeService.changeIterations(user, issue, iterations);
return Response.ok().build();
}
@Api(order=1400)
@Path("/{issueId}/fields")
@POST
public Response setFields(@PathParam("issueId") Long issueId, @NotNull @Api(exampleProvider = "getFieldsExample") Map<String, Serializable> fields) {View on GitHub (pinned to d44925c47c)
Solutions
- Grant the caller's role the schedule issues permission in the project.
- Retry with an account/token that has schedule permission.
- Manage iterations through the UI as a permitted user.
Example fix
// before: 401 Issue schedule permission required to set iterations // after: assign Schedule Issues permission to the role, then POST iterations again
Defensive patterns
Strategy: validation
Validate before calling
const perms = await getMyProjectPermissions(projectPath);
if (!perms.includes('SCHEDULE_ISSUES'))
throw new Error('Cannot set iterations: schedule issue permission missing for ' + projectPath); Type guard
function canSetIterations(subject, project) {
return subject?.effectivePermissions?.[project.path]?.includes('SCHEDULE_ISSUES') ?? false;
} Try / catch
try {
await api.setIterations(issueId, iterationIds);
} catch (e) {
if (e.status === 401 && /schedule permission required to set iterations/.test(e.message))
log.warn('Need Schedule Issues permission');
else throw e;
} Prevention
- Verify role permissions for the account used by schedulers/bots.
- Separate read tokens from write tokens and grant write tokens the minimum needed scopes.
- Document required permissions for each integration.
When it happens
Trigger: POST /api/issues/{issueId}/iterations with a list of iteration ids while the caller lacks schedule issues permission in the issue's project.
Common situations: Automation moving issues between iterations with an under-privileged token; users with only edit-issue but not schedule permission.
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
- Issue schedule permission required to set iterations
- No permission to add specified link for specified issues
- No permission to schedule issue. Remove iterationIds if you
- Issue schedule permission required to set own estimated time
- Issue schedule permission required to set own estimated time
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/77a932faa11454de.
Report an issue: GitHub.