sipeed/picoclaw · warning
qrcode expired, please try again
Error message
qrcode expired, please try again
What it means
Terminal state of the Weixin QR login: the status poll returned "expired", meaning the QR code shown to the user is no longer valid (Weixin QR codes live roughly a couple of minutes). The flow deliberately stops instead of silently re-requesting, so the operator must restart the login to get a fresh code.
Source
Thrown at pkg/channels/weixin/auth.go:125
"scaned_but_redirect received without redirect_host; continuing on current host",
)
continue
}
nextBaseURL := "https://" + statusResp.RedirectHost + "/"
nextAPI, nextErr := NewApiClient(nextBaseURL, "", opts.Proxy)
if nextErr != nil {
logger.WarnCF("weixin", "Failed to switch QR polling host", map[string]any{
"redirect_host": statusResp.RedirectHost,
"error": nextErr.Error(),
})
continue
}
pollAPI = nextAPI
logger.InfoCF("weixin", "Switched QR polling host", map[string]any{
"redirect_host": statusResp.RedirectHost,
})
case "expired":
return "", "", "", "", fmt.Errorf("qrcode expired, please try again")
default:
logger.WarnCF("weixin", "Unknown QR code status", map[string]any{
"status": statusResp.Status,
})
}
}
}
}
View on GitHub (pinned to 49183d7e8d)
Solutions
- Re-run the login command — it fetches and prints a fresh QR code
- Scan promptly after the QR renders; have WeChat ready before starting the command
- If expiring repeatedly in automation, trigger login only when a human is ready to scan
- Keep the terminal responsive (avoid slow SSH hops) so the code is visible immediately
Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
func isWeixinQRExpired(err error) bool {
return err != nil && strings.Contains(err.Error(), "qrcode expired")
} Try / catch
for {
_, _, _, _, err := weixin.Login(ctx, opts)
if err == nil || !isWeixinQRExpired(err) {
break
}
fmt.Println("QR expired, relaunching login...") // fresh code each iteration
} Prevention
- Scan immediately after the QR renders
- Have WeChat open before starting the login command
- In automation, gate login on operator readiness to avoid guaranteed expiries
- Prefer SSH sessions that render the QR without noticeable delay
When it happens
Trigger: Starting login, printing the QR, then not completing the scan+confirm within Weixin's QR validity window; also possible after a redirect to a new polling host (scaned_but_redirect path) consumed part of the window.
Common situations: Operator walks away after launching the login command; slow terminals/SSH sessions delaying when the QR is actually rendered; expired code discovered only when the user finally tries to scan; repeated expiries when login is scripted without a human ready.
Related errors
- failed to get qrcode: %w
- login timeout
- failed to create api client: %w
- login confirmed but missing bot_token or ilink_bot_id
- failed to load config: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/ab736e68bfd51bde.
Report an issue: GitHub.