{"record":{"id":"c748d1ffe9d66696","repo":"Tencent/WeKnora","slug":"failed-to-create-metaso-request-w","errorCode":null,"errorMessage":"failed to create Metaso request: %w","messagePattern":"failed to create Metaso request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/infrastructure/web_search/metaso.go","lineNumber":95,"sourceCode":"\t\treturn nil, fmt.Errorf(\"query is empty\")\n\t}\n\tif maxResults <= 0 {\n\t\tmaxResults = defaultMetasoResults\n\t}\n\tif maxResults > maxMetasoResults {\n\t\tmaxResults = maxMetasoResults\n\t}\n\n\tbody, err := json.Marshal(metasoSearchRequest{\n\t\tQuery: query, Scope: p.scope, Size: maxResults,\n\t\tIncludeSummary: true, IncludeRawContent: false, ConciseSnippet: true,\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to marshal Metaso request: %w\", err)\n\t}\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, p.baseURL, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create Metaso request: %w\", err)\n\t}\n\treq.Header.Set(\"Authorization\", \"Bearer \"+p.apiKey)\n\treq.Header.Set(\"Accept\", \"application/json\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tlogger.Infof(ctx, \"[WebSearch][Metaso] query=%q maxResults=%d scope=%s\", query, maxResults, p.scope)\n\tresp, err := p.client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to execute Metaso request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\trespBody, err := readMetasoResponseBody(resp.Body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, metasoHTTPError(resp.StatusCode, respBody)\n\t}","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/infrastructure/web_search/metaso.go#L77-L113","documentation":"Returned by MetasoProvider.Search when http.NewRequestWithContext fails to build the POST request against p.baseURL. This almost always means the baseURL string is not a valid absolute URL (unparseable by url.Parse), so the request can never be sent. It happens at construction time of the request, before any network I/O.","triggerScenarios":"Search (internal/infrastructure/web_search/metaso.go:95) with a malformed p.baseURL — e.g. empty string, \"metaso.cn/api/search\" without scheme, or a URL containing control characters/invalid characters.","commonSituations":"baseURL read from config/env with the scheme stripped; whitespace or newline accidentally included in the configured URL; empty config value defaulting to \"\"; misconfigured self-hosted proxy URL.","solutions":["Print/check p.baseURL and ensure it is a fully qualified URL with scheme, e.g. https://api.metaso.cn/v1/search.","Fix the config/env value supplying the base URL — remove stray whitespace and restore the https:// scheme.","If the base URL is configurable, validate it with url.Parse and require a scheme+host at startup.","If it should be hardcoded, revert to the provider's default constant instead of the overridden value."],"exampleFix":"// before: unvalidated config value\nbaseURL := os.Getenv(\"METASO_BASE_URL\")\nprovider, _ := NewMetasoProvider(params) // baseURL empty -> request creation fails\n\n// after: validate and default\nbaseURL := os.Getenv(\"METASO_BASE_URL\")\nif baseURL == \"\" {\n    baseURL = \"https://api.metaso.cn/v1/search\"\n}\nif u, err := url.Parse(baseURL); err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return nil, fmt.Errorf(\"invalid METASO_BASE_URL: %q\", baseURL)\n}","handlingStrategy":"validation","validationCode":"func validBaseURL(raw string) error {\n    u, err := url.Parse(raw)\n    if err != nil || u.Scheme == \"\" || u.Host == \"\" {\n        return fmt.Errorf(\"invalid base URL %q: must be absolute with scheme and host\", raw)\n    }\n    return nil\n}\n\n// before constructing the provider:\nif err := validBaseURL(cfg.MetasoBaseURL); err != nil { return err }","typeGuard":null,"tryCatchPattern":"provider, err := NewMetasoProvider(params)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to create Metaso request\") {\n        return nil, fmt.Errorf(\"check Metaso base URL configuration: %w\", err)\n    }\n    return nil, err\n}","preventionTips":["Validate configurable URLs with url.Parse at config-load time, requiring scheme and host.","Strip whitespace/newlines from URL config values as they are read.","Default to the provider's documented base URL instead of empty strings.","Add a startup smoke test that builds a request against the configured endpoint."],"tags":["http","url","config","web-search"],"backgroundTag":"invalid-url-config","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}