{"record":{"id":"43884f2f91b55709","repo":"theonedev/onedev","slug":"no-permission-to-schedule-issue-remove-iterationi","errorCode":null,"errorMessage":"No permission to schedule issue. Remove iterationIds if you want to create issue without scheduling it.","messagePattern":"No permission to schedule issue\\. Remove iterationIds if you want to create issue without scheduling it\\.","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/IssueResource.java","lineNumber":318,"sourceCode":"\t@SuppressWarnings(\"unused\")\n\tprivate static List<Map<String, Object>> getIssuesExample() {\n\t\tvar issues = new ArrayList<Map<String, Object>>();\n\t\tissues.add(ApiHelpUtils.getExampleMap(Issue.class, ValueInfo.Origin.READ_BODY));\n\t\treturn issues;\n\t}\n\n\t@Api(order=1000)\n    @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());","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/IssueResource.java#L300-L336","documentation":"POST /issues (createIssue) throws UnauthorizedException when the request data schedules the issue onto iterations (iterationIds is non-empty) but the authenticated user lacks the 'Schedule Issues' permission on the target project (SecurityUtils.canScheduleIssues). The message tells callers to omit iterationIds to create an unscheduled issue instead.","triggerScenarios":"POST /~api/issues with body containing iterationIds while the token's user cannot schedule issues in data.getProjectId()'s project — even if they can access the project and create issues generally.","commonSituations":"Automation that copies iteration assignments from another tracker with a token whose user only has 'Create Issues' permission; sprint-planning integrations pointing at projects where the service user wasn't granted scheduling rights.","solutions":["Grant your user the 'Schedule Issues' permission on the target project.","Remove iterationIds from the request body to create the issue unscheduled, then assign it later via the UI.","Use a token of a user who can schedule issues in that project (e.g. project maintainer).","Split the call: create without iterationIds and set the schedule as an admin afterwards."],"exampleFix":"// before\nPOST /~api/issues {\"projectId\":1, \"title\":\"x\", \"iterationIds\":[5]}\n// after (no schedule permission)\nPOST /~api/issues {\"projectId\":1, \"title\":\"x\"}","handlingStrategy":"validation","validationCode":"// omit iterationIds unless the user can schedule issues in the project\nif (iterationIds != null && !iterationIds.isEmpty() && !securityUtils.canScheduleIssues(project))\n    iterationIds = null; // create unscheduled","typeGuard":null,"tryCatchPattern":"try { client.createIssue(data); }\ncatch (UnauthorizedException e) {\n    if (e.getMessage().contains(\"Remove iterationIds\")) { data.setIterationIds(null); client.createIssue(data); }\n}","preventionTips":["Only include iterationIds in payloads when the token user has schedule permission.","Grant 'Schedule Issues' to integration accounts that do sprint planning.","Build payloads conditionally based on detected permissions, not statically."],"tags":["rest-api","issues","authorization","iterations"],"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"}