{"record":{"id":"3ffaf1c6f5acc2f9","repo":"sipeed/picoclaw","slug":"wecom-qr-code-expired-please-retry","errorCode":null,"errorMessage":"WeCom QR code expired, please retry","messagePattern":"WeCom QR code expired, please retry","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/picoclaw/internal/auth/wecom.go","lineNumber":307,"sourceCode":"\t\tstatus, err := queryWeComQRCodeStatus(timeoutCtx, opts, scode)\n\t\tif err != nil {\n\t\t\tif errors.Is(err, context.DeadlineExceeded) || errors.Is(timeoutCtx.Err(), context.DeadlineExceeded) {\n\t\t\t\treturn wecomQRBotInfo{}, fmt.Errorf(\"WeCom QR scan timed out after %s\", opts.PollTimeout)\n\t\t\t}\n\t\t\treturn wecomQRBotInfo{}, err\n\t\t}\n\n\t\tswitch strings.ToLower(status.Data.Status) {\n\t\tcase \"success\":\n\t\t\tif status.Data.BotInfo.BotID == \"\" || status.Data.BotInfo.Secret == \"\" {\n\t\t\t\treturn wecomQRBotInfo{}, fmt.Errorf(\"WeCom QR scan succeeded but bot credentials are missing\")\n\t\t\t}\n\t\t\treturn wecomQRBotInfo{\n\t\t\t\tBotID:  status.Data.BotInfo.BotID,\n\t\t\t\tSecret: status.Data.BotInfo.Secret,\n\t\t\t}, nil\n\t\tcase \"expired\":\n\t\t\treturn wecomQRBotInfo{}, fmt.Errorf(\"WeCom QR code expired, please retry\")\n\t\tcase \"scaned\", \"scanned\":\n\t\t\tif !scannedPrinted {\n\t\t\t\tfmt.Fprintln(opts.Writer, \"QR code scanned. Confirm the login in WeCom.\")\n\t\t\t\tscannedPrinted = true\n\t\t\t}\n\t\t}\n\n\t\tselect {\n\t\tcase <-timeoutCtx.Done():\n\t\t\tif errors.Is(timeoutCtx.Err(), context.DeadlineExceeded) {\n\t\t\t\treturn wecomQRBotInfo{}, fmt.Errorf(\"WeCom QR scan timed out after %s\", opts.PollTimeout)\n\t\t\t}\n\t\t\treturn wecomQRBotInfo{}, timeoutCtx.Err()\n\t\tcase <-time.After(opts.PollInterval):\n\t\t}\n\t}\n}\n","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/picoclaw/internal/auth/wecom.go#L289-L325","documentation":"The QR session status polled as 'expired': the WeCom relay invalidated the QR code because it was not scanned-and-confirmed within its validity window. The session's scode is dead; polling cannot succeed and the flow aborts with a retry instruction.","triggerScenarios":"User requested a QR code but scanned it too late; user scanned but never confirmed in the WeCom app within the validity window; relay expired the code server-side due to a newer code being issued for the same source.","commonSituations":"User starts login, gets distracted, then scans minutes later; generating a QR in a second terminal invalidates the first; slow phone camera making the user miss the window.","solutions":["Re-run the WeCom login command to get a fresh QR code and scan immediately","Avoid starting multiple simultaneous login sessions (a new code can invalidate the old one)","Use the printed QR Code Link URL directly if camera scanning is slow","Confirm the login promptly in the WeCom app after scanning"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"func isQRExpired(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"QR code expired\")\n}","tryCatchPattern":"info, err := pollWeComQRCodeResult(ctx, opts, session.SCode)\nif isQRExpired(err) {\n\t// automatically fetch a fresh QR and restart polling (bounded retries)\n}","preventionTips":["Scan immediately after the QR renders; do not reuse terminal scrollback QRs","Run only one login session at a time — new codes invalidate old ones"],"tags":["go","wecom","qr-code","expiry"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}