{"record":{"id":"e3fcd94555dbf38d","repo":"theonedev/onedev","slug":"time-tracking-needs-to-be-enabled-for-the-project-e3fcd9","errorCode":null,"errorMessage":"Time tracking needs to be enabled for the project","messagePattern":"Time tracking needs to be enabled for the project","errorType":"http","errorClass":"NotAcceptableException","httpStatus":406,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/ai/TodResource.java","lineNumber":626,"sourceCode":"        if (data.containsKey(\"description\")) {\n            if (!SecurityUtils.canModifyIssue(subject, issue))\n                throw new UnauthorizedException(\"No permission to update issue description\");\n            issueChangeService.changeDescription(user, issue, (String) data.remove(\"description\"));\n        }\n\n        var confidential = (Boolean) data.remove(\"confidential\");\n        if (confidential != null) {\n            if (!SecurityUtils.canModifyIssue(subject, issue))\n                throw new UnauthorizedException(\"No permission to update issue confidential\");\n            issueChangeService.changeConfidential(user, issue, confidential);\n        }\n\n        Integer ownEstimatedTime = (Integer) data.remove(\"ownEstimatedTime\");\n        if (ownEstimatedTime != null) {\n            if (!subscriptionService.isSubscriptionActive())\n                throw new NotAcceptableException(\"An active subscription is required for this feature\");\n            if (!issue.getProject().isTimeTracking())\n                throw new NotAcceptableException(\"Time tracking needs to be enabled for the project\");\n            if (!SecurityUtils.canScheduleIssues(subject, issue.getProject()))\n                throw new UnauthorizedException(\"Issue schedule permission required to set own estimated time\");\n            issueChangeService.changeOwnEstimatedTime(user, issue, ownEstimatedTime*60);\n        }\n\n        @SuppressWarnings(\"unchecked\")\n        List<String> iterationNames = (List<String>) data.remove(\"iterations\");\n        if (iterationNames != null) {\n            if (!SecurityUtils.canScheduleIssues(subject, issue.getProject()))\n                throw new UnauthorizedException(\"Issue schedule permission required to set iterations\");\n            var iterations = new ArrayList<Iteration>();\n            for (var iterationName : iterationNames) {\n                var iteration = iterationService.findInHierarchy(issue.getProject(), iterationName);\n                if (iteration == null)\n                    throw new NotFoundException(\"Iteration '\" + iterationName + \"' not found\");\n                iterations.add(iteration);\n            }\n            issueChangeService.changeIterations(user, issue, iterations);","sourceCodeStart":608,"sourceCodeEnd":644,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/ai/TodResource.java#L608-L644","documentation":"Even with an active subscription, setting \"ownEstimatedTime\" fails with NotAcceptableException(\"Time tracking needs to be enabled for the project\") when issue.getProject().isTimeTracking() is false. Each project must opt in to time tracking before estimated-time values can be changed.","triggerScenarios":"POST /edit-issue with \"ownEstimatedTime\" on a project whose Time Tracking setting is disabled, while the server subscription is active.","commonSituations":"New projects created without enabling time tracking; AI agents configured globally but used against projects with default settings; migrated projects missing the setting.","solutions":["Enable Time Tracking for the project: Project > Preferences/Settings > enable time tracking.","Remove \"ownEstimatedTime\" from the payload for projects where tracking is intentionally off.","Batch-enable time tracking across projects if tooling targets many projects.","Check the error ordering: fix this before asserting schedule permissions, as the subscription check precedes it."],"exampleFix":"// before\n// project \"proj\" has time tracking disabled\neditIssue(\"proj\", ref, {ownEstimatedTime: 4}) // 406\n// after\n// Project Settings -> enable Time Tracking, then:\neditIssue(\"proj\", ref, {ownEstimatedTime: 4})","handlingStrategy":"validation","validationCode":"// ensure the target project has time tracking enabled\nconst project = await getProject(projectPath);\nif ('ownEstimatedTime' in payload && !project.timeTracking) {\n  delete payload.ownEstimatedTime;\n  throw new Error(`Enable Time Tracking on project '${projectPath}' first`);\n}","typeGuard":null,"tryCatchPattern":"try { await editIssue(projectPath, ref, {ownEstimatedTime}); } catch (e) { if (e.status === 406 && /time tracking/i.test(e.message)) { await enableProjectTimeTracking(projectPath); return retry(); } throw e; }","preventionTips":["Enable Time Tracking in each project's settings before estimating hours","Enumerate target projects and validate the flag before bulk updates","Include time-tracking state in preflight checks of automation tooling","Standardize project templates with time tracking on for teams using estimates"],"tags":["configuration","time-tracking","http-406","project-settings"],"backgroundTag":"feature-not-enabled","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}