{"record":{"id":"3d49da01a9dbf677","repo":"iflytek/astron-agent","slug":"wechat-official-account-record-not-found-for-unbinding-appid","errorCode":null,"errorMessage":"WeChat official account record not found for unbinding: appid={}","messagePattern":"WeChat official account record not found for unbinding: appid=(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/wechat/impl/BotOffiaccountServiceImpl.java","lineNumber":125,"sourceCode":"\n        BotOffiaccount botOffiaccount = botOffiaccountMapper.selectOne(\n                new LambdaQueryWrapper<BotOffiaccount>()\n                        .eq(BotOffiaccount::getAppid, appid)\n                        .eq(BotOffiaccount::getStatus, BotOffiaccountStatusEnum.BOUND.getStatus()));\n        if (botOffiaccount != null) {\n            ChatBotBase botBase = chatBotBaseMapper.selectById(botOffiaccount.getBotId());\n\n            botOffiaccount.setStatus(BotOffiaccountStatusEnum.UNBOUND.getStatus());\n            botOffiaccount.setUpdateTime(LocalDateTime.now());\n            botOffiaccountMapper.updateById(botOffiaccount);\n\n            eventPublisher.publishEvent(new PublishChannelUpdateEvent(\n                    this, botOffiaccount.getBotId(), botOffiaccount.getUid(),\n                    botBase != null ? botBase.getSpaceId() : null, PublishChannelEnum.WECHAT, false));\n\n            log.info(\"WeChat official account unbinding successful: botId={}, appid={}\", botOffiaccount.getBotId(), appid);\n        } else {\n            log.warn(\"WeChat official account record not found for unbinding: appid={}\", appid);\n        }\n    }\n\n    @Override\n    public List<BotOffiaccount> getAccountList(String uid) {\n        return botOffiaccountMapper.selectList(\n                new LambdaQueryWrapper<BotOffiaccount>()\n                        .eq(BotOffiaccount::getUid, uid)\n                        .eq(BotOffiaccount::getStatus, BotOffiaccountStatusEnum.BOUND.getStatus())\n                        .orderByDesc(BotOffiaccount::getUpdateTime));\n    }\n\n    @Override\n    public BotOffiaccount getByAppid(String appid) {\n        return botOffiaccountMapper.selectOne(\n                new LambdaQueryWrapper<BotOffiaccount>()\n                        .eq(BotOffiaccount::getAppid, appid)\n                        .eq(BotOffiaccount::getStatus, BotOffiaccountStatusEnum.BOUND.getStatus()));","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/wechat/impl/BotOffiaccountServiceImpl.java#L107-L143","documentation":"WARN log from the WeChat official-account unbind flow: no BotOffiaccount record matched the given appid, so unbinding (including the PublishChannelUpdateEvent) is silently skipped. Callers get no error — the operation is a no-op.","triggerScenarios":"Calling unbind(appid) for an appid that was never bound, was already unbound, or whose rows are filtered (uid/tenant mismatch).","commonSituations":"Duplicate unbind callbacks from WeChat; appid typos; records deleted manually or by a concurrent process before unbind runs.","solutions":["Verify the appid exists in bot_offiaccount before calling unbind (query via getAccountList or mapper).","Make unbind return a boolean/result so callers can detect the not-found case instead of silently succeeding.","If idempotent unbind is desired, keep the log as info-level and document the no-op behavior."],"exampleFix":"// before\nlog.warn(\"WeChat official account record not found for unbinding: appid={}\", appid);\n// after\nlog.warn(\"WeChat official account record not found for unbinding: appid={}\", appid);\nthrow new BusinessException(ResponseEnum.OFFIACCOUNT_NOT_BOUND); // or return false","handlingStrategy":"validation","validationCode":"BotOffiaccount existing = botOffiaccountMapper.selectOne(new LambdaQueryWrapper<BotOffiaccount>().eq(BotOffiaccount::getAppid, appid));\nif (existing == null) { /* skip or error before calling unbind */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check binding existence before unbinding.","Treat unbind as idempotent and log at info level for repeats.","Validate appid source (avoid typos by selecting from a list rather than free input)."],"tags":["wechat","unbind","record-not-found","idempotency"],"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-19T12:17:13.211Z"}