{"record":{"id":"206e2dde353985b6","repo":"iflytek/astron-agent","slug":"bot-not-exists-206e2d","errorCode":"BOT_NOT_EXISTS","errorMessage":"BOT_NOT_EXISTS","messagePattern":"BOT_NOT_EXISTS","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/hub/src/main/java/com/iflytek/astron/console/hub/strategy/publish/impl/MarketPublishStrategy.java","lineNumber":49,"sourceCode":"@Component\n@RequiredArgsConstructor\npublic class MarketPublishStrategy implements PublishStrategy {\n\n    private final ChatBotBaseMapper chatBotBaseMapper;\n    private final ChatBotMarketMapper chatBotMarketMapper;\n    private final PublishChannelService publishChannelService;\n    private final ApplicationEventPublisher eventPublisher;\n\n    @Override\n    @Transactional(rollbackFor = Exception.class)\n    public ApiResult<Object> publish(Integer botId, Object publishData, String currentUid, Long spaceId) {\n        log.info(\"Publishing bot to market: botId={}, currentUid={}, spaceId={}\", botId, currentUid, spaceId);\n\n        try {\n            // 1. Validate bot permission\n            int hasPermission = chatBotBaseMapper.checkBotPermission(botId, currentUid, spaceId);\n            if (hasPermission == 0) {\n                throw new BusinessException(ResponseEnum.BOT_NOT_EXISTS);\n            }\n\n            // 2. Query current publish status\n            BotPublishQueryResult queryResult = chatBotMarketMapper.selectBotDetail(botId, currentUid, spaceId);\n            Integer currentStatus = queryResult != null ? queryResult.getBotStatus() : null;\n            String currentChannels = queryResult != null ? queryResult.getPublishChannels() : null;\n\n            // 3. Calculate new status and channels\n            Integer effectiveStatus = currentStatus != null ? currentStatus : ShelfStatusEnum.OFF_SHELF.getCode();\n\n            // Allow re-publishing even if already on shelf\n            if (ShelfStatusEnum.isOnShelf(effectiveStatus)) {\n                log.info(\"Bot already published, performing re-publish operation: botId={}\", botId);\n            }\n\n            if (!ShelfStatusEnum.isOffShelf(effectiveStatus) && !ShelfStatusEnum.isOnShelf(effectiveStatus)) {\n                throw new BusinessException(ResponseEnum.BOT_STATUS_NOT_ALLOW_PUBLISH);\n            }","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/hub/src/main/java/com/iflytek/astron/console/hub/strategy/publish/impl/MarketPublishStrategy.java#L31-L67","documentation":"MarketPublishStrategy.publish validates that the current user has permission over the bot via chatBotBaseMapper.checkBotPermission(botId, currentUid, spaceId) and throws BOT_NOT_EXISTS when the query returns 0 rows. The code deliberately reuses BOT_NOT_EXISTS to cover both 'bot does not exist' and 'bot not visible/owned in this space', so it is an authorization-shaped not-found error.","triggerScenarios":"Calling the market publish endpoint with a botId that doesn't exist, a bot belonging to another space (spaceId mismatch), or a currentUid that is not the bot owner — checkBotPermission returns 0 and the error is thrown before any status query.","commonSituations":"Caller passes a botId from a different space; uid/spaceId context lost after switching spaces in the UI; attempting to publish someone else's bot; bot hard-deleted while the client still shows it.","solutions":["Verify the bot exists and that you are its owner (or have publish permission) in the given space.","Ensure the request's spaceId context matches the space the bot belongs to (SpaceInfoUtil context).","Re-fetch the bot list for the current space and use a valid botId.","If legitimate admins need to publish others' bots, extend checkBotPermission to allow space-admin roles."],"exampleFix":"// before\nmarketPublish(botIdFromOtherSpace, uid, currentSpaceId); // permission check returns 0\n// after\nBot b = botService.getBotInSpace(botId, currentSpaceId);\nif (b == null) throw new BizError(\"bot not available in this space\");\nmarketPublish(b.getId(), uid, currentSpaceId);","handlingStrategy":"validation","validationCode":"Integer perm = chatBotBaseMapper.checkBotPermission(botId, currentUid, spaceId);\nif (perm == null || perm == 0) {\n    throw new AccessDeniedException(\"bot \" + botId + \" not found or not owned by user in space \" + spaceId);\n}","typeGuard":"boolean canManageBot(Long botId, String uid, Long spaceId) {\n    return botId != null && chatBotBaseMapper.checkBotPermission(botId, uid, spaceId) > 0;\n}","tryCatchPattern":"try {\n    marketPublishStrategy.publish(botId, uid, spaceId);\n} catch (BusinessException e) {\n    if (\"BOT_NOT_EXISTS\".equals(e.getCode())) {\n        refreshBotListForSpace(spaceId); // wrong id, wrong space, or no ownership\n    }\n    throw e;\n}","preventionTips":["Keep the uid/spaceId context in sync when the user switches spaces","Derive botId from a space-scoped bot list, never from stale client state","Hide publish actions for bots the current user doesn't own"],"tags":["not-found","authorization","bot-publish","java"],"backgroundTag":"entity-not-found","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"}