{"record":{"id":"af868a07bcb1675c","repo":"theonedev/onedev","slug":"an-active-subscription-is-required-for-this-featur-af868a","errorCode":null,"errorMessage":"An active subscription is required for this feature","messagePattern":"An active subscription is required for this feature","errorType":"http","errorClass":"NotAcceptableException","httpStatus":406,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/ai/TodResource.java","lineNumber":624,"sourceCode":"        }\n\n        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);","sourceCodeStart":606,"sourceCodeEnd":642,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/ai/TodResource.java#L606-L642","documentation":"Setting \"ownEstimatedTime\" via editIssue requires an active OneDev subscription; without one, NotAcceptableException(\"An active subscription is required for this feature\") is thrown. Time-tracking/scheduling fields are a commercial feature gated by subscription state.","triggerScenarios":"Including \"ownEstimatedTime\" (integer hours) in the edit-issue data map while subscriptionService.isSubscriptionActive() returns false (no license, expired subscription, or community edition).","commonSituations":"Running OneDev community edition while AI tooling tries to set time estimates; subscription expired and license not renewed; on-prem instance without license upload.","solutions":["Remove \"ownEstimatedTime\" from the payload if the feature isn't licensed.","Purchase/renew a OneDev subscription and upload the license under Administration > License.","Verify the license file is present and valid (check Administration for subscription status).","Use alternative free mechanisms (e.g. custom fields) to track estimates if staying on community edition."],"exampleFix":"// before\neditIssue(project, ref, {ownEstimatedTime: 8}) // 406 no subscription\n// after\neditIssue(project, ref, {}) // or activate subscription first","handlingStrategy":"validation","validationCode":"// avoid gated fields unless subscription is known active\nconst isLicensed = await getServerSubscriptionStatus(); // e.g. via admin API / license info\nif ('ownEstimatedTime' in payload && !isLicensed) {\n  delete payload.ownEstimatedTime;\n  console.warn('ownEstimatedTime requires an active OneDev subscription');\n}","typeGuard":null,"tryCatchPattern":"try { await editIssue(project, ref, {ownEstimatedTime}); } catch (e) { if (e.status === 406 && /subscription/i.test(e.message)) { fallbackToCustomField(); } else throw e; }","preventionTips":["Check Administration > License for active subscription before using gated fields","Track license expiry in ops monitoring for self-hosted instances","Design integrations to degrade to non-gated fields on community edition","Renew/upload the license before rolling out time-tracking automation"],"tags":["licensing","subscription","http-406","time-tracking"],"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-14T00:17:10.932Z"}