{"record":{"id":"44308603ed4ec9f6","repo":"sipeed/picoclaw","slug":"failed-to-get-wecom-qr-code-errcode-d-errmsg-s","errorCode":null,"errorMessage":"failed to get WeCom QR code: errcode=%d errmsg=%s","messagePattern":"failed to get WeCom QR code: errcode=(.+?) errmsg=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/picoclaw/internal/auth/wecom.go","lineNumber":262,"sourceCode":"\tif opts.Writer == nil {\n\t\topts.Writer = os.Stdout\n\t}\n\n\treturn opts\n}\n\nfunc fetchWeComQRCode(ctx context.Context, opts wecomQRFlowOptions) (wecomQRSession, error) {\n\tgenerateURL, err := buildWeComQRGenerateURL(opts.GenerateURL, opts.SourceID, wecomPlatformCode())\n\tif err != nil {\n\t\treturn wecomQRSession{}, err\n\t}\n\n\tvar resp wecomQRGenerateResponse\n\tif err := doWeComJSONGet(ctx, opts.HTTPClient, generateURL, &resp); err != nil {\n\t\treturn wecomQRSession{}, fmt.Errorf(\"failed to get WeCom QR code: %w\", err)\n\t}\n\tif resp.ErrCode != 0 {\n\t\treturn wecomQRSession{}, fmt.Errorf(\n\t\t\t\"failed to get WeCom QR code: errcode=%d errmsg=%s\",\n\t\t\tresp.ErrCode,\n\t\t\tresp.ErrMsg,\n\t\t)\n\t}\n\tif resp.Data.SCode == \"\" || resp.Data.AuthURL == \"\" {\n\t\treturn wecomQRSession{}, fmt.Errorf(\"failed to get WeCom QR code: response missing scode or auth_url\")\n\t}\n\n\treturn wecomQRSession{\n\t\tSCode:   resp.Data.SCode,\n\t\tAuthURL: resp.Data.AuthURL,\n\t}, nil\n}\n\nfunc pollWeComQRCodeResult(ctx context.Context, opts wecomQRFlowOptions, scode string) (wecomQRBotInfo, error) {\n\tif strings.TrimSpace(scode) == \"\" {\n\t\treturn wecomQRBotInfo{}, fmt.Errorf(\"missing WeCom QR scode\")","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/picoclaw/internal/auth/wecom.go#L244-L280","documentation":"The WeCom QR generate service answered HTTP 200 but with a business-level error: the response JSON carried a non-zero errcode field with errmsg. This is the relay/application layer rejecting the request — distinct from transport errors — and includes the numeric code and server message verbatim in the error string.","triggerScenarios":"The relay rejects the source/sourceID query parameters (invalid or blocked client source); rate limiting on the QR generate endpoint; relay-side outage returning errcode!=0; plat code parameter rejected for the detected platform.","commonSituations":"The login relay temporarily throttles burst logins; picoclaw version uses an outdated sourceID the relay no longer accepts; server-side incident returning generic errcode 500-style responses.","solutions":["Decode errcode: 4xx-style codes usually mean bad request params (update picoclaw), 5xx-style codes mean relay trouble (retry later)","Update picoclaw so the sourceID/plat parameters match what the relay currently accepts","Wait ~1 minute and retry if the code suggests throttling","Report the errcode/errmsg pair to the picoclaw maintainers if it persists on the latest version"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isWeComErrCode(err error) (code int, ok bool) {\n\tvar e wecomErr\n\tif errors.As(err, &e) { return e.code, true }\n\treturn 0, false\n}","tryCatchPattern":"if resp.ErrCode != 0 {\n\tif isThrottleCode(resp.ErrCode) {\n\t\ttime.Sleep(30 * time.Second)\n\t\t// retry generate once\n\t}\n\treturn wecomQRSession{}, fmt.Errorf(\"failed to get WeCom QR code: errcode=%d errmsg=%s\", resp.ErrCode, resp.ErrMsg)\n}","preventionTips":["Keep picoclaw updated so relay request params stay valid","Space out repeated login attempts to avoid throttle codes","Always log errcode/errmsg when reporting relay issues"],"tags":["go","wecom","api","error-code"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}