{"record":{"id":"7cd2d2347466d999","repo":"alibaba/nacos","slug":"access-denied","errorCode":"ACCESS_DENIED","errorMessage":"{errMsg}, owner: {owner}","messagePattern":"(.+?), owner: (.+?)","errorType":"exception","errorClass":"NacosApiException","httpStatus":403,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/service/skills/SkillOperationServiceImpl.java","lineNumber":418,"sourceCode":"            return overwriteUploadedSkill(namespaceId, skill, targetVersion, meta, true,\n                commitMsg);\n        }\n        if (SkillUploadPrecheckResult.ACTION_DELETE_DRAFT_AND_CREATE.equals(uploadAction)) {\n            return overwriteUploadedSkill(namespaceId, skill, targetVersion, meta, true,\n                commitMsg);\n        }\n        throw new NacosApiException(NacosException.INVALID_PARAM,\n            ErrorCode.PARAMETER_VALIDATE_ERROR, \"Unsupported uploadAction: \" + uploadAction);\n    }\n    \n    private void checkWritableUploadResource(AiResource meta) throws NacosException {\n        try {\n            VisibilityHelper.checkWritableResource(meta);\n        } catch (NacosException e) {\n            if (e.getErrCode() != NacosException.NO_RIGHT || StringUtils.isBlank(meta.getOwner())) {\n                throw e;\n            }\n            throw new NacosApiException(NacosException.NO_RIGHT, ErrorCode.ACCESS_DENIED,\n                e.getErrMsg() + \", owner: \" + meta.getOwner());\n        }\n    }\n    \n    /**\n     * Bootstrap a built-in skill from a ZIP archive (delegates to the overload with null source).\n     */\n    @Override\n    public void bootstrapSkillFromZip(String namespaceId, byte[] zipBytes) throws NacosException {\n        bootstrapSkillFromZip(namespaceId, zipBytes, null);\n    }\n    \n    /**\n     * Bootstrap a built-in skill from a ZIP archive. Skips if the skill already exists.\n     *\n     * <p>Unlike upload, this directly writes storage and creates a published meta + version\n     * in one step (no draft/review workflow), and also initializes the index manifest.</p>\n     */","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/service/skills/SkillOperationServiceImpl.java#L400-L436","documentation":"An ACCESS_DENIED (HTTP 403, ErrorCode ACCESS_DENIED/10001) from checkWritableUploadResource: VisibilityHelper.checkWritableResource already rejected the write (NO_RIGHT), and the resource meta carries an owner, so the original message is enriched with ', owner: <owner>' to tell the caller who controls the resource. It is an authorization failure, not a validation error.","triggerScenarios":"Uploading or overwriting a skill whose meta exists and is owned by another user/identity when the current caller is neither the owner nor an administrator with write permission.","commonSituations":"Shared namespace where a colleague owns the skill; logged in as the wrong user/service account; role lacks the write permission for that resource scope.","solutions":["Contact the listed owner (or an admin) to make the change or transfer ownership.","Authenticate as a user/role that has write permission on the resource.","Use precheckUploadSkillFromZip first — it returns PRECHECK_CODE_NO_PERMISSION without attempting the write."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Fetch meta and compare owner/identity before attempting a write upload.\nAiResource meta = resourceManager.findMeta(ns, name, RESOURCE_TYPE_SKILL);\nif (meta != null && !isWriter(meta.getOwner())) {\n    // surface 'owned by <owner>' to the user instead of attempting the upload\n}","typeGuard":null,"tryCatchPattern":"try {\n    skillOp.uploadSkillFromZip(req);\n} catch (NacosApiException e) {\n    if (e.getErrCode() == NacosException.NO_RIGHT\n            && ErrorCode.ACCESS_DENIED.getCode() == e.getDetailErrCode()) {\n        // tell the user who the owner is and that they need permission/transfer\n        showOwnerGuidance(e.getErrMsg());\n    } else {\n        throw e;\n    }\n}","preventionTips":["Check ownership (meta.owner) and your role before write/upload attempts.","Use precheckUploadSkillFromZip — it returns PRECHECK_CODE_NO_PERMISSION without mutating.","Request ownership transfer or admin rights rather than retrying as the wrong user."],"tags":["authz","permission","access-denied","ownership","upload","skill"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}