{"record":{"id":"2a0036dd77fbbd7d","repo":"Tencent/WeKnora","slug":"invalid-url-w","errorCode":null,"errorMessage":"invalid URL: %w","messagePattern":"invalid URL: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/datasource/connector/rss/client.go","lineNumber":53,"sourceCode":"\nfunc newClient(headers map[string]string) *client {\n\tcfg := utils.DefaultSSRFSafeHTTPClientConfig()\n\tcfg.Timeout = requestTimeout\n\treturn &client{\n\t\thttpClient: utils.NewSSRFSafeHTTPClient(cfg),\n\t\theaders:    headers,\n\t}\n}\n\n// fetch retrieves rawURL with SSRF validation and size limiting. Custom auth\n// headers are only attached when withAuthHeaders is true (feed fetches); article\n// pages on third-party domains must not receive feed credentials.\nfunc (c *client) fetch(ctx context.Context, rawURL string, maxSize int64, withAuthHeaders bool) ([]byte, error) {\n\tif err := utils.ValidateURLForSSRF(rawURL); err != nil {\n\t\treturn nil, fmt.Errorf(\"URL rejected: %w\", err)\n\t}\n\tif _, err := url.Parse(rawURL); err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid URL: %w\", err)\n\t}\n\n\tctx, cancel := context.WithTimeout(ctx, requestTimeout)\n\tdefer cancel()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, rawURL, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif withAuthHeaders {\n\t\tfor k, v := range c.headers {\n\t\t\treq.Header.Set(k, v)\n\t\t}\n\t}\n\tif req.Header.Get(\"User-Agent\") == \"\" {\n\t\treq.Header.Set(\"User-Agent\", defaultUserAgent)\n\t}","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/datasource/connector/rss/client.go#L35-L71","documentation":"This error is returned by the RSS client's fetch when the raw URL string cannot be parsed by net/url.Parse. Note that url.Parse is very lenient; this only fires for genuinely malformed URL syntax (e.g. control characters, invalid percent-escapes like %zz, or a bare colon in the first path segment). By the time this line runs, SSRF validation has already passed, so this is the last URL-syntax gate before the HTTP request is built.","triggerScenarios":"A feed URL or article URL stored in the datasource config contains characters that net/url rejects: invalid percent-encoding sequences (e.g. \"https://example.com/feed%zz\"), ASCII control characters or unescaped spaces/newlines pasted into the URL field, or a first path segment containing a colon (e.g. \"https://example.com/foo:bar\").","commonSituations":"Admins paste feed URLs from emails/docs with trailing whitespace or smart quotes; URLs built by string concatenation with unescaped user input; migrations import feed lists from CSV where a comma or newline slipped into the URL cell.","solutions":["Print the URL with %q and check for control characters, whitespace, or invalid %-escapes; trim and re-enter the feed URL in the datasource config.","Percent-encode the offending characters (e.g. use url.PathEscape on path components, or strings.TrimSpace on pasted values) before saving the config.","If the URL comes from user input, validate at ingestion time with url.ParseRequestURI and reject/mend it there instead of failing at fetch time."],"exampleFix":"// before\ndata, err := cli.fetchFeed(ctx, feedURL)\n// after\ntrimmed := strings.TrimSpace(feedURL)\nif _, perr := url.Parse(trimmed); perr != nil {\n    return fmt.Errorf(\"configured feed URL is malformed: %w\", perr)\n}\ndata, err := cli.fetchFeed(ctx, trimmed)","handlingStrategy":"validation","validationCode":"func validFeedURL(raw string) error {\n    trimmed := strings.TrimSpace(raw)\n    if trimmed == \"\" {\n        return errors.New(\"empty feed URL\")\n    }\n    u, err := url.Parse(trimmed)\n    if err != nil {\n        return fmt.Errorf(\"malformed URL: %w\", err)\n    }\n    if u.Scheme != \"http\" && u.Scheme != \"https\" {\n        return fmt.Errorf(\"unsupported scheme %q\", u.Scheme)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Trim and normalize pasted URLs (strip whitespace, smart quotes) at config ingestion time.","Always specify scheme explicitly (https://) instead of relying on defaults.","Unit-test feed URL lists with url.Parse before saving datasource config.","Reject URLs containing control characters with a strings.ContainsFunc check."],"tags":["go","url-parsing","rss","config"],"backgroundTag":"invalid-url","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}