{"record":{"id":"9d82b956bdacb1f8","repo":"iflytek/astron-agent","slug":"insufficient-permissions-9d82b9","errorCode":"INSUFFICIENT_PERMISSIONS","errorMessage":"ResponseEnum.INSUFFICIENT_PERMISSIONS","messagePattern":"ResponseEnum\\.INSUFFICIENT_PERMISSIONS","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/skill/SkillFileService.java","lineNumber":513,"sourceCode":"        if (spaceId != null) {\n            wrapper.eq(SkillFile::getSpaceId, spaceId);\n        } else {\n            if (StringUtils.isBlank(uid)) {\n                throw new BusinessException(ResponseEnum.UNAUTHORIZED);\n            }\n            wrapper.isNull(SkillFile::getSpaceId).eq(SkillFile::getUid, uid);\n        }\n        return wrapper;\n    }\n\n    private void assertExplicitScope(String uid, Long spaceId) {\n        if (StringUtils.isBlank(uid)) {\n            throw new BusinessException(ResponseEnum.UNAUTHORIZED);\n        }\n        if (spaceId != null\n                && (spaceUserService == null\n                        || spaceUserService.getRole(spaceId, uid) == null)) {\n            throw new BusinessException(ResponseEnum.INSUFFICIENT_PERMISSIONS);\n        }\n    }\n\n    private SkillFile getScopedEntry(Long id) {\n        if (id == null) {\n            throw new BusinessException(ResponseEnum.PARAM_ERROR);\n        }\n        SkillFile entry = getOne(scopeQuery().eq(SkillFile::getId, id), false);\n        if (entry == null) {\n            throw new BusinessException(ResponseEnum.PARAM_ERROR);\n        }\n        return entry;\n    }\n\n    private void assertParentFolder(Long parentId) {\n        if (parentId == 0L) {\n            return;\n        }","sourceCodeStart":495,"sourceCodeEnd":531,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/skill/SkillFileService.java#L495-L531","documentation":"SkillFileService.assertExplicitScope additionally verifies space membership: when a spaceId is supplied, the uid must have a role in that space (via spaceUserService.getRole). If the space user service is unavailable or returns null (user not a member), BusinessException(INSUFFICIENT_PERMISSIONS) is thrown, blocking access to another space's skill files.","triggerScenarios":"Calling a SkillFileService operation with a spaceId where the authenticated uid has no membership/role in that space (spaceUserService.getRole(spaceId, uid) == null), or the spaceUserService bean is missing (SkillFileService.java:513).","commonSituations":"Users sharing skill-file ids across teams/spaces and accessing them with their own account; revoked membership where the client still holds old space ids; misconfigured Spring context where the SpaceUserService dependency isn't wired in a test/manual bean setup.","solutions":["Add the user to the target space (grant a role) via space management, then retry.","Verify the uid actually belongs to spaceId; use the user's own space instead.","If membership was revoked intentionally, obtain access through a member of the space.","In tests/local runs, ensure spaceUserService is injected rather than left null."],"exampleFix":"// before\nskillFileService.updateContent(reqWithOtherSpaceId); // INSUFFICIENT_PERMISSIONS\n\n// after\nspaceUserService.addMember(spaceId, uid, Role.MEMBER); // grant access first\nskillFileService.updateContent(reqWithOtherSpaceId);","handlingStrategy":"validation","validationCode":"if (spaceId != null && spaceUserService.getRole(spaceId, uid) == null) {\n  throw new IllegalStateException(\"user \" + uid + \" has no role in space \" + spaceId);\n}","typeGuard":null,"tryCatchPattern":"try {\n  skillFileService.updateContent(req);\n} catch (BusinessException e) {\n  if (\"INSUFFICIENT_PERMISSIONS\".equals(e.getCode())) {\n    // request space access or fall back to the user's own space\n  } else throw e;\n}","preventionTips":["Check space membership (getRole) in the UI before exposing other spaces' resources.","Refresh space roles client-side after membership changes.","Never hardcode spaceIds from other users; resolve the caller's spaces dynamically."],"tags":["permissions","space-membership","authorization","skill-files"],"backgroundTag":"insufficient-permissions","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}