{"record":{"id":"0af6867777ebb59c","repo":"iflytek/astron-agent","slug":"permission-not-belong-space","errorCode":"PERMISSION_NOT_BELONG_SPACE","errorMessage":"PERMISSION_NOT_BELONG_SPACE","messagePattern":"PERMISSION_NOT_BELONG_SPACE","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"console/backend/hub/src/main/java/com/iflytek/astron/console/hub/controller/chat/ChatMessageController.java","lineNumber":427,"sourceCode":"        debugChatReqDto.setDebugSessionId(debugRequest.getDebugSessionId());\n        debugChatReqDto.setPrompt(debugRequest.getPrompt());\n        debugChatReqDto.setMessages(messageList);\n        debugChatReqDto.setUid(uid);\n        debugChatReqDto.setOpenedTool(debugRequest.getOpenedTool());\n        debugChatReqDto.setMcpServerUrls(debugRequest.getMcpServerUrls());\n        debugChatReqDto.setSkills(debugRequest.getSkills());\n        debugChatReqDto.setTools(debugRequest.getTools());\n        debugChatReqDto.setWorkflows(debugRequest.getWorkflows());\n        debugChatReqDto.setModel(debugRequest.getModel());\n        debugChatReqDto.setModelId(debugRequest.getModelId());\n        debugChatReqDto.setMaasDatasetList(maasDatasetList);\n        debugChatReqDto.setPersonalityConfig(debugRequest.getPersonalityConfig());\n\n        Long spaceId = SpaceInfoUtil.getSpaceId();\n        if (spaceId != null && !SpaceInfoUtil.checkUserBelongSpace()) {\n            log.warn(\"Reject bot debug request from non-member, uid: {}, spaceId: {}\", uid, spaceId);\n            SseEmitterUtil.completeWithError(sseEmitter,\n                    I18nUtil.getMessage(ResponseEnum.PERMISSION_NOT_BELONG_SPACE.getMessageKey()));\n            return sseEmitter;\n        }\n        debugChatReqDto.setSpaceId(spaceId);\n        if (!agentWorkflowRuntimeService.checkWorkflowsAccessible(uid, spaceId, debugRequest.getWorkflows())) {\n            SseEmitterUtil.completeWithError(sseEmitter, \"Workflow not accessible\");\n            return sseEmitter;\n        }\n\n        try {\n            sendStartSignal(sseEmitter, sseId,\n                    new ChatContext(uid, 0L, debugRequest.getBotId() == null ? 0 : debugRequest.getBotId()));\n            botChatService.debugChatMessageBot(debugChatReqDto, sseEmitter, sseId);\n            return sseEmitter;\n        } catch (Exception e) {\n            log.error(\"Bot debug error, sseId: {}\", sseId, e);\n            SseEmitterUtil.completeWithError(sseEmitter, \"Chat service exception: \" + e.getMessage());\n            return sseEmitter;\n        }","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/hub/src/main/java/com/iflytek/astron/console/hub/controller/chat/ChatMessageController.java#L409-L445","documentation":"The botDebug SSE endpoint refuses requests when a space context is active but the user is not a member of that space (SpaceInfoUtil.checkUserBelongSpace() is false). It completes the emitter with the localized I18n message for ResponseEnum.PERMISSION_NOT_BELONG_SPACE. This is a tenancy/authorization guard preventing users from debugging bots in spaces they do not belong to.","triggerScenarios":"Calling the botDebug endpoint with a spaceId resolved from the request context (SpaceInfoUtil.getSpaceId() != null) while the authenticated user is not a member of that space.","commonSituations":"User switched space in another tab leaving a stale space header/context; account removed from the space but the client kept the space selected; debugging a bot by hardcoding another team's spaceId; token/identity mismatch after membership revocation.","solutions":["Switch to a space the current user is a member of before debugging","Re-check space membership (re-fetch user/space info) and refresh the space context in the client","If membership was just granted, re-login or refresh the token so membership is reflected","Verify the space-selection header/cookie matches the intended workspace"],"exampleFix":"// before\ndebugBot({ botId, workflows, ... }); // uses stale space header\n// after\nawait refreshSpaceContext(); // re-sync current space from server\nif (!currentSpace.isMember) { promptSpaceSwitch(); return; }\ndebugBot({ botId, workflows, ... });","handlingStrategy":"try-catch","validationCode":"const spaces = await getUserSpaces();\nif (!spaces.some(s => s.id === currentSpaceId)) { promptSpaceSwitch(); return; }","typeGuard":"function isMemberOfSpace(user, spaceId) { return user != null && Array.isArray(user.spaces) && user.spaces.some(s => s.id === spaceId); }","tryCatchPattern":"sse.onerror = () => { if (lastError === 'PERMISSION_NOT_BELONG_SPACE') promptSpaceSwitch(); };","preventionTips":["Re-sync active space after membership changes","Listen for space-switch events across tabs and update context","Never hardcode spaceIds in debug calls"],"tags":["authorization","multi-tenancy","sse","permission"],"backgroundTag":"permission-denied","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"}