{"record":{"id":"22b0fded10652beb","repo":"sipeed/picoclaw","slug":"invalid-wecom-qr-page-url-w","errorCode":null,"errorMessage":"invalid WeCom QR page URL: %w","messagePattern":"invalid WeCom QR page URL: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/picoclaw/internal/auth/wecom.go","lineNumber":378,"sourceCode":"}\n\nfunc buildWeComQRQueryURL(baseURL, scode string) (string, error) {\n\tu, err := url.Parse(baseURL)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid WeCom QR query URL: %w\", err)\n\t}\n\n\tquery := u.Query()\n\tquery.Set(\"scode\", scode)\n\tu.RawQuery = query.Encode()\n\n\treturn u.String(), nil\n}\n\nfunc buildWeComQRCodePageURL(baseURL, sourceID, scode string) (string, error) {\n\tu, err := url.Parse(baseURL)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid WeCom QR page URL: %w\", err)\n\t}\n\n\tquery := u.Query()\n\tquery.Set(\"source\", sourceID)\n\tquery.Set(\"sourceID\", sourceID)\n\tquery.Set(\"scode\", scode)\n\tu.RawQuery = query.Encode()\n\n\treturn u.String(), nil\n}\n\nfunc doWeComJSONGet(ctx context.Context, client *http.Client, targetURL string, out any) error {\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, targetURL, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tresp, err := client.Do(req)","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/picoclaw/internal/auth/wecom.go#L360-L396","documentation":"url.Parse rejected opts.QRCodePageURL in buildWeComQRCodePageURL, which builds the human-clickable page URL (source + sourceID + scode) printed next to the rendered QR. Failures are the same rare class as 133/134: an unparseable base URL from a custom option, config override, or test stub — the defaults (wecomQRPageEndpoint) are valid constants.","triggerScenarios":"Custom QRCodePageURL containing control characters or invalid escapes; overrides sourced from env vars with embedded whitespace/newlines; programmatic option construction with unvalidated input.","commonSituations":"Self-hosted relay page URL typo; fork customizing the page endpoint; CI test doubles with sloppy URLs.","solutions":["Validate QRCodePageURL the same way as the other two endpoints before starting the flow","Prefer library defaults; only override with a known-good absolute URL","Sanitize any env-sourced URL (trim spaces/newlines)","Test custom URLs with url.Parse in a unit test for your configuration layer"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if _, err := url.Parse(opts.QRCodePageURL); err != nil {\n\treturn fmt.Errorf(\"QRCodePageURL %q is not a valid URL: %w\", opts.QRCodePageURL, err)\n}","typeGuard":"func isInvalidURL(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"invalid URL\")\n}","tryCatchPattern":null,"preventionTips":["Validate the page URL alongside generate/query URLs in one preflight pass","Use httptest.Server URLs in tests to guarantee parseability"],"tags":["go","wecom","url","validation","config"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}