{"record":{"id":"c9b0948fd5c0bfb4","repo":"chenhg5/cc-connect","slug":"login-confirmed-but-ilink-bot-id-missing","errorCode":null,"errorMessage":"login confirmed but ilink_bot_id missing","messagePattern":"login confirmed but ilink_bot_id missing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cc-connect/weixin.go","lineNumber":365,"sourceCode":"\t\t\tnewURL := strings.TrimSpace(newQR.QRCodeImgContent)\n\t\t\tif newURL != \"\" {\n\t\t\t\tfmt.Println(\"请扫描新二维码：\")\n\t\t\t\tfmt.Printf(\"URL: %s\\n\\n\", newURL)\n\t\t\t\ttryPrintTerminalQRCode(newURL)\n\t\t\t}\n\t\t\t// 过期刷新时同步更新 QR 图片文件\n\t\t\tif opts.QRImage != \"\" {\n\t\t\t\tif err := saveQRCodeImage(newURL, opts.QRImage); err != nil {\n\t\t\t\t\tfmt.Fprintf(os.Stderr, \"Warning: failed to update QR image: %v\\n\", err)\n\t\t\t\t} else {\n\t\t\t\t\tfmt.Printf(\"QR code updated at: %s\\n\\n\", opts.QRImage)\n\t\t\t\t}\n\t\t\t}\n\t\t\ttime.Sleep(time.Second)\n\t\t\tcontinue\n\t\tcase \"confirmed\":\n\t\t\tif strings.TrimSpace(status.IlinkBotID) == \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"login confirmed but ilink_bot_id missing\")\n\t\t\t}\n\t\t\tif strings.TrimSpace(status.BotToken) == \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"login confirmed but bot_token missing\")\n\t\t\t}\n\t\t\tfmt.Println(\"\\n✅ 已与微信建立连接。\")\n\t\t\treturn &weixinQRLoginResult{\n\t\t\t\tBotToken:    strings.TrimSpace(status.BotToken),\n\t\t\t\tIlinkBotID:  strings.TrimSpace(status.IlinkBotID),\n\t\t\t\tBaseURL:     strings.TrimSpace(status.BaseURL),\n\t\t\t\tIlinkUserID: strings.TrimSpace(status.IlinkUserID),\n\t\t\t}, nil\n\t\tdefault:\n\t\t\ttime.Sleep(time.Second)\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"等待扫码超时，请重试\")\n}","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/cmd/cc-connect/weixin.go#L347-L383","documentation":"On \"confirmed\" poll status the login succeeded on WeChat's side, and runWeixinQRLoginFlow expects the server to hand back the bot identity. If status.IlinkBotID is blank it returns \"login confirmed but ilink_bot_id missing\" — the auth handshake completed but the response payload lacks the required bot identifier, so no usable credentials can be produced.","triggerScenarios":"`cc-connect weixin setup` QR flow reaches case \"confirmed\" in the poll loop, strings.TrimSpace(status.IlinkBotID) == \"\" — the status endpoint returned confirmed without ilink_bot_id.","commonSituations":"ilink backend bug or partial deployment omitting the field; API schema change renaming ilink_bot_id; account in a state where the bot was never fully provisioned despite login; mocked/stub APIBaseURL returning minimal payloads.","solutions":["Retry `cc-connect weixin setup` — a server-side glitch may be transient.","Capture the confirmed status response (debug mode) and check whether ilink_bot_id is present under a different key (API drift).","Verify APIBaseURL targets the current production API version; update client if the schema changed.","Confirm the WeChat account actually completed bot provisioning on the ilink platform.","Fall back to `cc-connect weixin bind --token ...` with a manually obtained token."],"exampleFix":"// before: hard fail on missing field\nif strings.TrimSpace(status.IlinkBotID) == \"\" {\n    return nil, fmt.Errorf(\"login confirmed but ilink_bot_id missing\")\n}\n\n// after: log payload for diagnosis before failing\nif strings.TrimSpace(status.IlinkBotID) == \"\" {\n    slog.Error(\"weixin: confirmed status missing ilink_bot_id\", \"status\", status)\n    return nil, fmt.Errorf(\"login confirmed but ilink_bot_id missing\")\n}","handlingStrategy":"type-guard","validationCode":"// Validate the confirmed status shape before consuming:\nif status.Status == \"confirmed\" && strings.TrimSpace(status.IlinkBotID) == \"\" {\n    slog.Warn(\"server returned confirmed without ilink_bot_id; retrying\")\n}","typeGuard":"func hasBotID(s *pollStatus) bool {\n    return s != nil && strings.TrimSpace(s.IlinkBotID) != \"\"\n}","tryCatchPattern":"res, err := runWeixinQRLoginFlow(ctx, opts)\nif err != nil && strings.Contains(err.Error(), \"ilink_bot_id missing\") {\n    // upstream returned incomplete payload; retry or bind manually\n    return fmt.Errorf(\"server sent incomplete login result; try again or use bind --token\")\n}","preventionTips":["Keep the client in sync with the ilink status API schema","Test against the real production endpoint, not stubs, before release","Log the full status payload on this error to aid upstream bug reports","Provide the token-bind path as a documented fallback"],"tags":["weixin","api","missing-field"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}