{"record":{"id":"2b1b9594c1559229","repo":"Tencent/WeKnora","slug":"invalid-searxng-base-url-must-not-contain-query-o","errorCode":null,"errorMessage":"invalid SearXNG base_url: must not contain query or fragment","messagePattern":"invalid SearXNG base_url: must not contain query or fragment","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/infrastructure/web_search/searxng.go","lineNumber":53,"sourceCode":"\n// ValidateSearxngBaseURL validates a SearXNG instance URL: must be a non-empty,\n// absolute http(s) URL, and must pass the SSRF whitelist check. Shared between\n// the service-layer parameter validation and the provider constructor so that\n// \"save\" and \"use\" never disagree.\nfunc ValidateSearxngBaseURL(rawURL string) error {\n\tbase := strings.TrimSpace(rawURL)\n\tif base == \"\" {\n\t\treturn fmt.Errorf(\"base_url is required for SearXNG provider\")\n\t}\n\tparsed, err := url.Parse(base)\n\tif err != nil || parsed.Scheme == \"\" || parsed.Host == \"\" {\n\t\treturn fmt.Errorf(\"invalid SearXNG base_url: must be an absolute http(s) URL\")\n\t}\n\tif parsed.Scheme != \"http\" && parsed.Scheme != \"https\" {\n\t\treturn fmt.Errorf(\"invalid SearXNG base_url scheme: %s\", parsed.Scheme)\n\t}\n\tif parsed.RawQuery != \"\" || parsed.Fragment != \"\" {\n\t\treturn fmt.Errorf(\"invalid SearXNG base_url: must not contain query or fragment\")\n\t}\n\tif err := utils.ValidateURLForSSRF(base); err != nil {\n\t\treturn fmt.Errorf(\"invalid SearXNG base_url: %w\", err)\n\t}\n\treturn nil\n}\n\n// NewSearxngProvider builds a SearXNG provider from tenant parameters.\nfunc NewSearxngProvider(params types.WebSearchProviderParameters) (interfaces.WebSearchProvider, error) {\n\tbase := strings.TrimSpace(params.BaseURL)\n\tif err := ValidateSearxngBaseURL(base); err != nil {\n\t\treturn nil, err\n\t}\n\n\tclient, err := NewSearchHTTPClient(defaultSearxngTimeout, params.ProxyURL)\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/infrastructure/web_search/searxng.go#L35-L71","documentation":"The SearXNG base_url contains a query string or fragment (?... or #...), which the validator rejects because the provider constructs its own request paths and parameters; user-supplied query/fragment would be lost or corrupt request construction.","triggerScenarios":"NewSearxngProvider or save validation with base_url like \"https://searx.example.com/search?q=x\" or \"https://searx.example.com/#results\".","commonSituations":"Users pasting the full search results URL from their browser instead of the instance base URL, bookmark URLs containing anchors, deep links with session parameters.","solutions":["Strip the query string and fragment, keeping only scheme://host[/basepath]","Use the instance root URL, e.g. https://searx.example.com, not a search results link","If the instance lives under a path, keep only the path: https://host/searxng","Document/validate the field at save time to catch pasted search URLs"],"exampleFix":"// before\nbaseURL := \"https://searx.example.com/search?q=test#top\"\n// after\nbaseURL := \"https://searx.example.com\"","handlingStrategy":"validation","validationCode":"u, err := url.Parse(baseURL)\nif err == nil && (u.RawQuery != \"\" || u.Fragment != \"\") {\n    return fmt.Errorf(\"base_url must not contain query or fragment: %s\", baseURL)\n}","typeGuard":null,"tryCatchPattern":"if err := web_search.ValidateSearxngBaseURL(cfg.BaseURL); err != nil {\n    if strings.Contains(err.Error(), \"query or fragment\") {\n        return fmt.Errorf(\"use the instance base URL without ?query or #fragment\")\n    }\n    return err\n}","preventionTips":["Strip query/fragment from pasted URLs before saving: u.RawQuery, u.Fragment = \"\", \"\"","Instruct users to paste the instance root URL, not a search results link","Sanitize URLs in the config UI on blur/change","Validate at save time with ValidateSearxngBaseURL"],"tags":["url","validation","searxng","configuration"],"backgroundTag":"invalid-url-format","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}