sipeed/picoclaw · error
failed to query WeCom QR result: errcode=%d errmsg=%s
Error message
failed to query WeCom QR result: errcode=%d errmsg=%s
What it means
The QR status query endpoint returned HTTP 200 with a non-zero errcode in the JSON body. The relay rejected the poll itself — most commonly an invalid or already-consumed scode — and the numeric code plus server errmsg are embedded in the error text.
Source
Thrown at cmd/picoclaw/internal/auth/wecom.go:337
}
return wecomQRBotInfo{}, timeoutCtx.Err()
case <-time.After(opts.PollInterval):
}
}
}
func queryWeComQRCodeStatus(ctx context.Context, opts wecomQRFlowOptions, scode string) (wecomQRQueryResponse, error) {
queryURL, err := buildWeComQRQueryURL(opts.QueryURL, scode)
if err != nil {
return wecomQRQueryResponse{}, err
}
var resp wecomQRQueryResponse
if err := doWeComJSONGet(ctx, opts.HTTPClient, queryURL, &resp); err != nil {
return wecomQRQueryResponse{}, fmt.Errorf("failed to query WeCom QR result: %w", err)
}
if resp.ErrCode != 0 {
return wecomQRQueryResponse{}, fmt.Errorf(
"failed to query WeCom QR result: errcode=%d errmsg=%s",
resp.ErrCode,
resp.ErrMsg,
)
}
return resp, nil
}
func buildWeComQRGenerateURL(baseURL, sourceID string, platformCode int) (string, error) {
u, err := url.Parse(baseURL)
if err != nil {
return "", fmt.Errorf("invalid WeCom QR generate URL: %w", err)
}
query := u.Query()
query.Set("source", sourceID)
query.Set("sourceID", sourceID)View on GitHub (pinned to 49183d7e8d)
Solutions
- Re-run the login to obtain a fresh scode and keep exactly one session active
- Match the errcode against the relay's documented codes (auth-token-invalid style codes mean the scode is dead; throttle codes mean back off)
- Retry after a minute if the code indicates throttling
- Update picoclaw if the relay changed session semantics between versions
Defensive patterns
Strategy: try-catch
Type guard
func isInvalidScode(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to query WeCom QR result: errcode=")
} Try / catch
if resp.ErrCode != 0 {
if isThrottleCode(resp.ErrCode) {
// back off one interval and keep polling
} else {
return wecomQRQueryResponse{}, fmt.Errorf("failed to query WeCom QR result: errcode=%d errmsg=%s", resp.ErrCode, resp.ErrMsg)
}
} Prevention
- Avoid concurrent login sessions that invalidate each other's scode
- Log the errcode to distinguish session-death from throttling
When it happens
Trigger: Polling with a scode that expired or was invalidated server-side (a newer QR generated for the same source); relay garbage-collected the session between polls; source throttling returning an error code.
Common situations: Two login sessions racing; long pause between generate and poll letting the relay purge the scode; relay restart dropping in-memory sessions.
Related errors
- failed to get WeCom QR code: errcode=%d errmsg=%s
- WeCom QR scan timed out after %s
- failed to query WeCom QR result: %w
- error fetching models: %w
- failed to load config: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/8f5a8d85b144803f.
Report an issue: GitHub.