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

  1. Re-run the login to obtain a fresh scode and keep exactly one session active
  2. Match the errcode against the relay's documented codes (auth-token-invalid style codes mean the scode is dead; throttle codes mean back off)
  3. Retry after a minute if the code indicates throttling
  4. 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

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


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/8f5a8d85b144803f. Report an issue: GitHub.