sipeed/picoclaw · error

login failed: %w

Error message

login failed: %w

What it means

Top-level wrapper for any failure in weixin.PerformLoginInteractive (pkg/channels/weixin/auth.go:25), the WeChat-personal QR login flow. Underlying causes visible through %w: 'failed to create api client' (bad BaseURL/proxy), 'failed to get qrcode' (initial HTTP call to ilinkai.weixin.qq.com), or 'login timeout' (default 5-minute scan deadline exceeded).

Source

Thrown at cmd/picoclaw/internal/auth/weixin.go:56

	cmd.Flags().IntVar(&timeout, "timeout", 300, "Login timeout in seconds")

	return cmd
}

func runWeixinOnboard(baseURL, proxy string, timeout time.Duration) error {
	fmt.Println("Starting Weixin (WeChat personal) login...")
	fmt.Println()

	botToken, userID, accountID, returnedBaseURL, err := weixin.PerformLoginInteractive(
		context.Background(),
		weixin.AuthFlowOpts{
			BaseURL: baseURL,
			Timeout: timeout,
			Proxy:   proxy,
		},
	)
	if err != nil {
		return fmt.Errorf("login failed: %w", err)
	}

	fmt.Println()
	fmt.Println("✅ Login successful!")
	fmt.Printf("   Account ID : %s\n", accountID)
	if userID != "" {
		fmt.Printf("   User ID    : %s\n", userID)
	}
	fmt.Println()

	// Prefer the server-returned base URL (may be region-specific)
	effectiveBaseURL := returnedBaseURL
	if effectiveBaseURL == "" {
		effectiveBaseURL = baseURL
	}

	if err := saveWeixinConfig(botToken, effectiveBaseURL, proxy); err != nil {
		fmt.Printf("⚠️  Could not auto-save to config: %v\n", err)

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Unwrap the cause: 'login timeout' means re-run and scan within the window; 'failed to get qrcode' means network/endpoint trouble
  2. Verify https://ilinkai.weixin.qq.com/ is reachable from your network (curl)
  3. Remove or fix proxy settings (HTTP_PROXY/HTTPS_PROXY) and any custom --base-url
  4. Increase the timeout option for slow interactive environments and retry
  5. On mobile/VPN networks that block WeChat domains, switch networks before logging in

Example fix

// before
if err != nil {
	return fmt.Errorf("login failed: %w", err)
}

// after: give an actionable hint for the most common cause
if err != nil {
	if strings.Contains(err.Error(), "login timeout") {
		return fmt.Errorf("login failed: QR code was not confirmed within the timeout — re-run and scan+confirm in WeChat promptly: %w", err)
	}
	return fmt.Errorf("login failed (check network/proxy and retry): %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

// Validate custom endpoints before starting the interactive flow
if baseURL != "" {
	if _, err := url.Parse(baseURL); err != nil {
		return fmt.Errorf("invalid --base-url %q: %w", baseURL, err)
	}
}

Type guard

func isLoginTimeout(err error) bool {
	return err != nil && strings.Contains(err.Error(), "login timeout")
}

Try / catch

botToken, userID, accountID, returnedBaseURL, err := weixin.PerformLoginInteractive(ctx, opts)
if err != nil {
	if isLoginTimeout(err) {
		// re-run flow and instruct user to scan+confirm promptly
	}
	return fmt.Errorf("login failed: %w", err)
}

Prevention

When it happens

Trigger: Custom BaseURL or proxy that breaks the API client; GetQRCode HTTP failure against https://ilinkai.weixin.qq.com/; user not scanning/confirming within opts.Timeout (default 5m); network drop during the 2-second-interval status polling.

Common situations: User starts weixin login and does not scan in 5 minutes; wrong region blocking WeChat login servers; proxy env vars misconfigured; typo'd --base-url flag.

Related errors


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