sipeed/picoclaw · error

invalid WeCom QR generate URL: %w

Error message

invalid WeCom QR generate URL: %w

What it means

url.Parse rejected opts.GenerateURL while constructing the QR generate request. Go's url.Parse almost never fails (it accepts most strings), so this indicates a severely malformed URL — control characters, a bad escape sequence, or an empty/blank base URL that a custom option or test injected instead of the wecomQRGenerateEndpoint default.

Source

Thrown at cmd/picoclaw/internal/auth/wecom.go:350

	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)
	query.Set("plat", strconv.Itoa(platformCode))
	u.RawQuery = query.Encode()

	return u.String(), nil
}

func buildWeComQRQueryURL(baseURL, scode string) (string, error) {
	u, err := url.Parse(baseURL)
	if err != nil {
		return "", fmt.Errorf("invalid WeCom QR query URL: %w", err)
	}

	query := u.Query()

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Print the GenerateURL value being used and eyeball it for newlines, quotes, or raw spaces
  2. Use the library default (omit the override) unless you truly need a custom relay
  3. Percent-encode any dynamic values instead of concatenating raw strings
  4. In tests, use httptest.Server URLs, which always parse

Example fix

// before
generateURL, err := buildWeComQRGenerateURL(opts.GenerateURL, opts.SourceID, wecomPlatformCode())

// after: fail fast on a bad override before entering the flow
if _, err := url.Parse(opts.GenerateURL); err != nil {
	return fmt.Errorf("invalid GenerateURL configured: %q: %w", opts.GenerateURL, err)
}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := url.Parse(opts.GenerateURL); err != nil {
	return fmt.Errorf("GenerateURL %q is not a valid URL: %w", opts.GenerateURL, err)
}

Type guard

func isInvalidURL(err error) bool {
	var uerr *url.Error
	return errors.As(err, &uerr) || strings.Contains(err.Error(), "invalid WeCom QR")
}

Prevention

When it happens

Trigger: Programmatically overriding wecomQRFlowOptions.GenerateURL with an unvalidated string containing control chars or bad percent-escapes; unit tests passing an empty or malformed URL; a config/env override introducing whitespace or quotes into the URL.

Common situations: Fork code or tests customizing the relay endpoints; copy-paste of a URL with a stray newline; URL built by string concatenation with an unencoded value.

Related errors


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