{"record":{"id":"9ef927e0bdd6900e","repo":"theonedev/onedev","slug":"issue-schedule-permission-required-to-set-own-esti-9ef927","errorCode":null,"errorMessage":"Issue schedule permission required to set own estimated time. Remove ownEstimatedTime if you want to create issue without setting own estimated time.","messagePattern":"Issue schedule permission required to set own estimated time\\. Remove ownEstimatedTime if you want to create issue without setting own estimated time\\.","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/IssueResource.java","lineNumber":326,"sourceCode":"    @POST\n    public Long createIssue(@NotNull @Valid IssueOpenData data) {\n\t\tvar subject = SecurityUtils.getSubject();\n    \tvar user = SecurityUtils.getUser(subject);\n    \t\n    \tProject project = projectService.load(data.getProjectId());\n    \tif (!SecurityUtils.canAccessProject(project))\n\t\t\tthrow new UnauthorizedException();\n\n\t\tif (data.getIterationIds() != null && !data.getIterationIds().isEmpty() && !SecurityUtils.canScheduleIssues(project))\n\t\t\tthrow new UnauthorizedException(\"No permission to schedule issue. Remove iterationIds if you want to create issue without scheduling it.\");\n\n\t\tif (data.getOwnEstimatedTime() != null) {\n \t\t\tif (!subscriptionService.isSubscriptionActive())\t\t\t\n\t\t\t\tthrow new NotAcceptableException(\"An active subscription is required for this feature\");\n\t\t\tif (!project.isTimeTracking())\n\t\t\t\tthrow new NotAcceptableException(\"Time tracking needs to be enabled for the project\");\n\t\t\tif (!SecurityUtils.canScheduleIssues(project))\n\t\t\t\tthrow new UnauthorizedException(\"Issue schedule permission required to set own estimated time. Remove ownEstimatedTime if you want to create issue without setting own estimated time.\");\n\t\t}\n\n\t\tvar issueSetting = settingService.getIssueSetting();\n\t\t\n\t\tIssue issue = new Issue();\n\t\tissue.setTitle(data.getTitle());\n\t\tissue.setDescription(data.getDescription());\n\t\tissue.setConfidential(data.isConfidential());\n\t\tissue.setProject(project);\n\t\tissue.setSubmitDate(new Date());\n\t\tissue.setSubmitter(user);\n\t\tissue.setState(issueSetting.getInitialStateSpec().getName());\n\t\tif (data.getOwnEstimatedTime() != null)\n\t\t\tissue.setOwnEstimatedTime(data.getOwnEstimatedTime());\n\n\t\tif (data.getIterationIds() != null) {\n\t\t\tfor (Long iterationId : data.getIterationIds()) {\n\t\t\t\tIteration iteration = iterationService.load(iterationId);","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/IssueResource.java#L308-L344","documentation":"Thrown when the API caller sets ownEstimatedTime on issue creation but the authenticated user lacks the issue schedule permission for the target project. Even with an active subscription and time tracking enabled, SecurityUtils.canScheduleIssues(project) must return true. Returns HTTP 401 (UnauthorizedException) with a self-explanatory message.","triggerScenarios":"POST to /api/issues (createIssue) with ownEstimatedTime != null while the current user is not authorized to schedule issues in the project (missing schedule issue permission in project/role settings).","commonSituations":"Service accounts or regular users without the 'Schedule issues' permission attempting to automate issue creation with time estimates; permission grants changed or role downgraded.","solutions":["Grant the user/role 'Schedule issues' permission in the project or parent permissions.","Remove ownEstimatedTime from the request if estimates are not required.","Perform the call as a user with schedule permission (e.g., an access token of an admin or project maintainer)."],"exampleFix":"// before (user lacks permission)\nPOST /api/issues {\"title\":\"t\",\"ownEstimatedTime\":120}\n// after: either drop the field\nPOST /api/issues {\"title\":\"t\"}\n// or grant Schedule Issues permission to the role in Project -> Access Management","handlingStrategy":"validation","validationCode":"const perms = await getMyProjectPermissions(projectPath);\nif (body.ownEstimatedTime != null && !perms.includes('SCHEDULE_ISSUES'))\n  throw new Error('Missing schedule issue permission; drop ownEstimatedTime or request access');","typeGuard":"function canSchedule(user, project) {\n  return user?.projectPermissions?.[project.path]?.includes('SCHEDULE_ISSUES') ?? false;\n}","tryCatchPattern":"try {\n  await api.createIssue(body);\n} catch (e) {\n  if (e.status === 401 && /Issue schedule permission/.test(e.message))\n    retryWithoutEstimates(body);\n  else throw e;\n}","preventionTips":["Use service accounts with explicitly granted schedule permission for automations.","Verify effective role permissions after any access-management change.","Prefer omitting estimates in shared automation payloads."],"tags":["rest-api","permissions","authorization","time-tracking"],"backgroundTag":"insufficient-permissions","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}