{"record":{"id":"a4ec22c907925bfd","repo":"iflytek/astron-agent","slug":"user-no-approvel","errorCode":"USER_NO_APPROVEL","errorMessage":"USER_NO_APPROVEL","messagePattern":"USER_NO_APPROVEL","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"warning","filePath":"console/backend/hub/src/main/java/com/iflytek/astron/console/hub/controller/chat/ChatListController.java","lineNumber":166,"sourceCode":"\n        if (chatBotMarket != null) {\n            validateMarketBotPermissions(chatBotMarket, uid);\n        } else {\n            validatePrivateBotPermissions(botId, uid);\n        }\n    }\n\n    /**\n     * Validate market bot permissions\n     *\n     * @param chatBotMarket Chat bot market object\n     * @param uid User unique identifier\n     * @throws BusinessException Throws business exception if no approved permission\n     */\n    private void validateMarketBotPermissions(ChatBotMarket chatBotMarket, String uid) {\n        if (ShelfStatusEnum.isOffShelf(chatBotMarket.getBotStatus()) &&\n                !chatBotMarket.getUid().equals(uid)) {\n            throw new BusinessException(ResponseEnum.USER_NO_APPROVEL);\n        }\n    }\n\n    /**\n     * Validate private bot permissions\n     *\n     * @param botId Bot ID\n     * @param uid User ID\n     */\n    private void validatePrivateBotPermissions(Integer botId, String uid) {\n        ChatBotBase chatBotBase = chatBotDataService.findById(botId)\n                .orElseThrow(() -> new BusinessException(ResponseEnum.BOT_NOT_EXISTS));\n\n        if (!chatBotBase.getUid().equals(uid)) {\n            validateSpacePermissions(chatBotBase);\n        }\n    }\n","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/hub/src/main/java/com/iflytek/astron/console/hub/controller/chat/ChatListController.java#L148-L184","documentation":"USER_NO_APPROVEL is thrown by validateMarketBotPermissions when a market bot is currently off-shelf (ShelfStatusEnum.isOffShelf) and the requesting uid is not the bot owner. Off-shelf market bots are only visible/usable to their owner, so other users are denied access to chat lists built on them.","triggerScenarios":"Fetching or using a chat list that references a market bot whose botStatus is off-shelf while the current authenticated user is not chatBotMarket.uid; accessing a bot right after the owner took it off the marketplace.","commonSituations":"Bot was unpublished/removed from the market between saving the chat list and using it; sharing a chat link built on an off-shelf bot with a colleague; environment where the bot owner uid differs due to data seeding.","solutions":["Ask the bot owner to re-publish (put back on shelf) the market bot","Use a different, on-shelf bot for the chat list","If you believe you are the owner, verify the token resolves to the owner's uid","Update the chat list to reference an accessible bot"],"exampleFix":"// before\nchatList.botId = offShelfMarketBot.id; // off-shelf, not owner\n// after\nchatList.botId = publishedBot.id; // ShelfStatus ON_SHELF","handlingStrategy":"try-catch","validationCode":"const bot = await getMarketBot(botId); if (bot.botStatus === 'OFF_SHELF' && bot.uid !== currentUid) throw new Error('bot is off-shelf and not owned by you');","typeGuard":"const canUseMarketBot = (bot, uid) => bot.botStatus !== 'OFF_SHELF' || bot.uid === uid;","tryCatchPattern":"try { await useChatList(botId); } catch (e) { if (e.code === 'USER_NO_APPROVEL') { suggestAlternativeOnShelfBot(); } else throw e; }","preventionTips":["Check shelf status before persisting a chat list on a market bot","Handle off-shelf transitions gracefully (bots can be unpublished anytime)","Share chat lists only for on-shelf bots","Refresh bot status periodically in long-lived UI sessions"],"tags":["permission","bot-marketplace","authorization"],"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"}