theonedev/onedev · error · UnauthorizedException

Issue schedule permission required to set own estimated time

Error message

Issue schedule permission required to set own estimated time

What it means

After subscription and time-tracking checks pass, editIssue verifies SecurityUtils.canScheduleIssues(subject, issue.getProject()); failing that it throws UnauthorizedException("Issue schedule permission required to set own estimated time"). This is a distinct scheduling authorization separate from general issue-modify rights.

Source

Thrown at server-core/src/main/java/io/onedev/server/ai/TodResource.java:628

                throw new UnauthorizedException("No permission to update issue description");
            issueChangeService.changeDescription(user, issue, (String) data.remove("description"));
        }

        var confidential = (Boolean) data.remove("confidential");
        if (confidential != null) {
            if (!SecurityUtils.canModifyIssue(subject, issue))
                throw new UnauthorizedException("No permission to update issue confidential");
            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);
        }

View on GitHub (pinned to d44925c47c)

Solutions

  1. Grant the user the permission that allows scheduling issues on the project (project role/authorizations covering schedule issues).
  2. Use a token of an account that already has schedule permission for time-tracking updates.
  3. Remove "ownEstimatedTime" from automated payloads if schedule permission cannot be granted.
  4. Verify the permission in the UI (if the estimated-time field is editable there, the API call should succeed).

Example fix

// before
editIssue(project, ref, {ownEstimatedTime: 2}) // 403 schedule perm
// after
// admin grants schedule-issues permission to the user, then:
editIssue(project, ref, {ownEstimatedTime: 2})
Defensive patterns

Strategy: validation

Validate before calling

// check schedule permission before sending estimated time
const canSchedule = await userCanScheduleIssues(projectPath); // via permission API or role config
if ('ownEstimatedTime' in payload && !canSchedule) {
  delete payload.ownEstimatedTime;
  throw new Error('User lacks schedule-issues permission on project');
}

Try / catch

try { await editIssue(projectPath, ref, {ownEstimatedTime}); } catch (e) { if (e.status === 403 && /schedule/i.test(e.message)) { requestPermissionGrant(); } else throw e; }

Prevention

When it happens

Trigger: Sending "ownEstimatedTime" in the edit-issue payload with an authenticated user who can modify the issue but lacks the schedule-issues permission on the project (subscription active, time tracking enabled).

Common situations: Developers with edit rights but without scheduling role trying to log estimates; service tokens with narrow grants; role changes removing schedule permission while tools still attempt time updates.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/b2d19c33b7404f1c. Report an issue: GitHub.