{"record":{"id":"27e9dca5759d56b4","repo":"iflytek/astron-agent","slug":"bot-status-not-allow-publish","errorCode":"BOT_STATUS_NOT_ALLOW_PUBLISH","errorMessage":"BOT_STATUS_NOT_ALLOW_PUBLISH","messagePattern":"BOT_STATUS_NOT_ALLOW_PUBLISH","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"warning","filePath":"console/backend/hub/src/main/java/com/iflytek/astron/console/hub/strategy/publish/impl/MarketPublishStrategy.java","lineNumber":66,"sourceCode":"            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            }\n\n            Integer newStatus = ShelfStatusEnum.ON_SHELF.getCode();\n            String newChannels = publishChannelService.updatePublishChannels(\n                    currentChannels, PublishChannelEnum.MARKET.getCode(), true);\n\n            // 4. Parse market-specific publish data\n            if (publishData != null) {\n                log.debug(\"Market publish data: {}\", JSON.toJSONString(publishData));\n                // TODO: Parse market-specific data like category, tags, visibility settings\n            }\n\n            // 5. Handle market data synchronization directly\n            boolean isFirstPublish = currentStatus == null;\n            handleBotMarketSync(botId, currentUid, spaceId, newStatus, newChannels, isFirstPublish);\n\n            // 6. Publish event to trigger bot-type-specific operations (workflow version creation, etc.)\n            eventPublisher.publishEvent(new BotPublishStatusChangedEvent(","sourceCodeStart":48,"sourceCodeEnd":84,"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#L48-L84","documentation":"MarketPublishStrategy.publish allows re-publishing when a bot is already on shelf, but throws BOT_STATUS_NOT_ALLOW_PUBLISH when the bot's effective status is neither off-shelf nor on-shelf — i.e. an intermediate/invalid status (e.g. under review, blocked, or pending removal) forbids publishing. It is a status-guard before flipping the bot to ON_SHELF.","triggerScenarios":"publish() runs when effectiveStatus (from BotPublishQueryResult.getBotStatus(), possibly defaulted) is a value for which both ShelfStatusEnum.isOffShelf and ShelfStatusEnum.isOnShelf return false — e.g. status codes representing 'in review', 'rejected', or an unknown numeric status.","commonSituations":"Bot is stuck in a moderation/review state and the user clicks publish again; a status value was written by a newer/older code version that ShelfStatusEnum doesn't map; publishChannels/status row corrupted by a failed previous publish.","solutions":["Check the bot's current publish status; complete or cancel the pending review before publishing.","If the status is a stale/unknown value, correct the bot's status in the bot market table to OFF_SHELF and retry.","Confirm ShelfStatusEnum covers every status value persisted by current code; add mappings if a status is missing.","Retry after the moderation flow finishes rather than forcing a publish."],"exampleFix":"// before\nif (!isOffShelf(status) && !isOnShelf(status)) {\n    throw new BusinessException(ResponseEnum.BOT_STATUS_NOT_ALLOW_PUBLISH);\n}\n// after\nif (ShelfStatusEnum.IN_REVIEW.getCode().equals(status)) {\n    throw new BusinessException(ResponseEnum.BOT_IN_REVIEW); // clearer error for this state\n}\nif (!isOffShelf(status) && !isOnShelf(status)) {\n    throw new BusinessException(ResponseEnum.BOT_STATUS_NOT_ALLOW_PUBLISH);\n}","handlingStrategy":"validation","validationCode":"BotPublishQueryResult r = chatBotMarketMapper.selectBotDetail(botId, uid, spaceId);\nInteger status = r != null ? r.getBotStatus() : null;\nif (status != null && !ShelfStatusEnum.isOffShelf(status) && !ShelfStatusEnum.isOnShelf(status)) {\n    throw new IllegalStateException(\"bot status \" + status + \" (e.g. in review) does not allow publishing\");\n}","typeGuard":"boolean isPublishableStatus(Integer status) {\n    return status != null && (ShelfStatusEnum.isOffShelf(status) || ShelfStatusEnum.isOnShelf(status));\n}","tryCatchPattern":"try {\n    marketPublishStrategy.publish(botId, uid, spaceId);\n} catch (BusinessException e) {\n    if (\"BOT_STATUS_NOT_ALLOW_PUBLISH\".equals(e.getCode())) {\n        showStatus(\"bot is under review or blocked; resolve its current status first\");\n    }\n    throw e;\n}","preventionTips":["Check the bot's shelf status and finish pending review before publishing","Ensure ShelfStatusEnum maps every status value the DB can contain","Fix stuck status rows back to OFF_SHELF after failed publishes"],"tags":["state-machine","shelf-status","bot-publish","java"],"backgroundTag":"invalid-state-transition","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"}