{"record":{"id":"aaaafc940201cddb","repo":"alibaba/nacos","slug":"20002-aaaafc","errorCode":"20002","errorMessage":"Current editing version is not draft: {version}","messagePattern":"Current editing version is not draft: (.+?)","errorType":"exception","errorClass":"NacosApiException","httpStatus":400,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/service/resource/AiResourceManager.java","lineNumber":698,"sourceCode":"        String version,\n        String status, String description, String storageJson) {\n        aiResourceVersionPersistService.updateStorageAndDesc(namespaceId, name, type, version,\n            storageJson, description);\n        aiResourceVersionPersistService.updateStatus(namespaceId, name, type, version, status);\n    }\n    \n    /**\n     * Find a version row and verify it is in draft status.\n     *\n     * @throws NacosApiException if version not found or not in draft status\n     */\n    public AiResourceVersion requireDraftVersion(String namespaceId, String name, String type,\n        String version)\n        throws NacosException {\n        AiResourceVersion v =\n            aiResourceVersionPersistService.find(namespaceId, name, type, version);\n        if (v == null || !isDraftVersion(v)) {\n            throw new NacosApiException(NacosException.INVALID_PARAM,\n                ErrorCode.PARAMETER_VALIDATE_ERROR,\n                \"Current editing version is not draft: \" + version);\n        }\n        return v;\n    }\n    \n    /**\n     * Find a version row and verify it can be submitted.\n     *\n     * <p>Submit accepts a draft version for review, a reviewing version as an idempotent\n     * no-op, or a reviewed version for resubmission. Online and offline versions are\n     * rejected.</p>\n     *\n     * @throws NacosApiException if version not found or not in a submittable status\n     */\n    public AiResourceVersion requireSubmitVersion(String namespaceId, String name, String type,\n        String version)\n        throws NacosException {","sourceCodeStart":680,"sourceCodeEnd":716,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/service/resource/AiResourceManager.java#L680-L716","documentation":"Thrown by requireDraftVersion when the resolved version row is null OR its status is not 'draft'. Used by operations that only make sense against an in-progress draft (e.g. editing content before submit). Maps to INVALID_PARAM (20002) even when the row is missing, because the precondition (a draft exists) is what failed.","triggerScenarios":"Calling an edit/update-draft API with a version name that does not exist, or with a version whose status has already moved on to 'reviewing', 'reviewed', 'online', or 'offline'. Also when two concurrent callers advance the same draft out of draft status.","commonSituations":"Stale client that cached a draft version name after it was submitted; version lifecycle advanced server-side (review/publish) while client still believes it is a draft; typo in version name.","solutions":["Re-fetch the resource's version info to see the current status of the named version.","If the version advanced past draft, create a new draft from the latest base version instead of editing the old one.","If the version name is wrong, correct it to the actual current editing version.","Ensure no concurrent workflow is mutating the same draft between fetch and update."],"exampleFix":"// before: editing a version that was already submitted\nmanager.requireDraftVersion(ns, name, type, \"v1.0\"); // throws\n// after: re-read version info and create a fresh draft from latest\nString draftVersion = manager.createDraft(ns, name, type, /*basedOnVersion*/ null);","handlingStrategy":"validation","validationCode":"// Confirm the version is a draft before invoking a draft-only operation.\nAiResourceVersion v = aiResourceVersionPersistService.find(ns, name, type, version);\nif (v == null || !\"draft\".equalsIgnoreCase(v.getStatus())) {\n    return rejectDraft(version);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return manager.requireDraftVersion(ns, name, type, version);\n} catch (NacosApiException e) {\n    if (e.getErrCode() == NacosException.INVALID_PARAM\n        && e.getMessage().contains(\"not draft\")) {\n        // refresh version info and create a new draft from latest\n    } else { throw e; }\n}","preventionTips":["Always re-fetch version status before editing a draft.","Avoid caching draft version names across user sessions.","Use single-flight for edit operations to prevent concurrent status changes."],"tags":["ai-registry","version-lifecycle","draft","validation"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}