sipeed/picoclaw · error

failed to get qrcode: %w

Error message

failed to get qrcode: %w

What it means

The Weixin login flow requested a QR code from ilink/bot/get_bot_qrcode and the call failed: either a transport error (network down, DNS failure, TLS issue, proxy refused) or a non-200 response (error 667) from the iLink endpoint. The QR code is the entry point of the whole interactive login, so the flow aborts before printing anything to scan.

Source

Thrown at pkg/channels/weixin/auth.go:48

		opts.BaseURL = "https://ilinkai.weixin.qq.com/"
	}
	if opts.BotType == "" {
		opts.BotType = "3" // Default iLink Bot Type
	}
	if opts.Timeout == 0 {
		opts.Timeout = 5 * time.Minute
	}

	api, err := NewApiClient(opts.BaseURL, "", opts.Proxy)
	if err != nil {
		return "", "", "", "", fmt.Errorf("failed to create api client: %w", err)
	}
	pollAPI := api

	logger.InfoC("weixin", "Requesting Weixin QR code...")
	qrResp, err := api.GetQRCode(ctx, opts.BotType)
	if err != nil {
		return "", "", "", "", fmt.Errorf("failed to get qrcode: %w", err)
	}

	fmt.Println("\n=======================================================")
	fmt.Println("Please scan the following QR code with WeChat to login:")
	fmt.Println("=======================================================")
	fmt.Println()

	// Create Small QR
	qrconfig := qrterminal.Config{
		Level:      qrterminal.L,
		Writer:     os.Stdout,
		HalfBlocks: true,
	}
	qrterminal.GenerateWithConfig(qrResp.QrcodeImgContent, qrconfig)

	fmt.Printf("\nQR Code Link: %s\n\n", qrResp.QrcodeImgContent)
	fmt.Println("Waiting for scan...")

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Verify outbound reachability: curl https://ilinkai.weixin.qq.com/ from the same host/environment
  2. If a proxy is required, set opts.Proxy correctly (and make sure it is well-formed, see error 666)
  3. Re-run the login command — transient server errors resolve on retry
  4. If a custom BaseURL was set, drop it and use the default
  5. In containers, ensure DNS and CA certificates are functional (TLS handshake failure surfaces here)
Defensive patterns

Strategy: retry

Validate before calling

// preflight connectivity before starting the interactive flow
func reachable(ctx context.Context, base string) bool {
    req, _ := http.NewRequestWithContext(ctx, http.MethodHead, base, nil)
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return false
    }
    defer resp.Body.Close()
    return resp.StatusCode < 500
}

Type guard

func isWeixinQRCodeFetchFail(err error) bool {
    return err != nil && strings.HasPrefix(err.Error(), "failed to get qrcode")
}

Try / catch

var qrErr error
for attempt := 0; attempt < 3; attempt++ {
    if _, _, _, _, qrErr = weixin.Login(ctx, opts); qrErr == nil || !isWeixinQRCodeFetchFail(qrErr) {
        break
    }
    time.Sleep(2 * time.Second)
}

Prevention

When it happens

Trigger: GetQRCode (a GET to ilink/bot/get_bot_qrcode with bot_type, default "3") failing due to: no internet connectivity from the host, DNS for ilinkai.weixin.qq.com not resolving, a firewall blocking the endpoint, an invalid proxy, or the server returning 4xx/5xx.

Common situations: Running the login command in a container/sandbox without outbound network; corporate proxy required but not configured; Weixin iLink endpoint temporarily down or geo-blocked; typo'd custom BaseURL; system clock skew breaking TLS.

Related errors


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