{"record":{"id":"fbb2d90f2ddad306","repo":"quickwit-oss/quickwit","slug":"root-url-should-be-well-formed","errorCode":null,"errorMessage":"root url should be well-formed","messagePattern":"root url should be well-formed","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-rest-client/src/rest_client.rs","lineNumber":67,"sourceCode":"\nstruct Transport {\n    base_url: Url,\n    api_url: Url,\n    client: ClientWithMiddleware,\n}\n\nimpl Transport {\n    fn new(\n        endpoint: Url,\n        connect_timeout: Timeout,\n        ca_cert: Option<Certificate>,\n        client_identity: Option<Identity>,\n        num_retries: u32,\n    ) -> Self {\n        let base_url = endpoint;\n        let api_url = base_url\n            .join(\"api/v1/\")\n            .expect(\"root url should be well-formed\");\n        let mut reqwest_client_builder = ReqwestClientBuilder::new();\n        if let Some(duration) = connect_timeout.as_duration_opt() {\n            reqwest_client_builder = reqwest_client_builder.connect_timeout(duration);\n        }\n        if let Some(ca_cert) = ca_cert {\n            reqwest_client_builder = reqwest_client_builder\n                .tls_built_in_root_certs(false)\n                .add_root_certificate(ca_cert);\n        }\n        if let Some(identity) = client_identity {\n            reqwest_client_builder = reqwest_client_builder.identity(identity);\n        }\n        let retry_policy = ExponentialBackoff::builder()\n            .retry_bounds(Duration::from_secs(1), Duration::from_mins(1))\n            .build_with_max_retries(num_retries);\n        let retry_transient_middleware = RetryTransientMiddleware::new_with_policy(retry_policy);\n        let reqwest_client = reqwest_client_builder\n            .build()","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-rest-client/src/rest_client.rs#L49-L85","documentation":"The REST client constructor joins \"api/v1/\" onto the endpoint URL and asserts the result is a well-formed URL with expect. reqwest's Url::join only errors if the base URL cannot be a base (e.g. a non-hierarchical scheme like 'mailto:' or a relative URL), since 'api/v1/' is itself valid. A panic means the endpoint passed to RestClient::new was not an absolute HTTP(S) URL.","triggerScenarios":"Constructing a RestClient with an endpoint that is not a valid absolute base URL — e.g. 'localhost:7280' without a scheme parsed as scheme 'localhost', a URL like 'mailto:foo@bar', an empty string, or a config value with whitespace/typos such as 'http:/...' or 'http:/localhost:7280'.","commonSituations":"Misconfigured QW_REST_CLIENT endpoint env var or config file missing the 'http://' prefix; passing a relative path instead of a full URL when embedding the rest client in another tool; environment-specific config where the scheme was stripped by templating.","solutions":["Prefix the endpoint with a scheme: use 'http://localhost:7280' or 'https://your-host' rather than 'localhost:7280'.","Validate the endpoint with url::Url::parse(endpoint) before constructing the client and fail with a clear message.","Check the config/env source for templating or trimming bugs that removed 'http(s)://'."],"exampleFix":"// before\nlet client = RestClient::new(\"localhost:7280\", ...);\n// after\nlet endpoint = Url::parse(\"localhost:7280\")\n    .or_else(|_| Url::parse(&format!(\"http://{}\", \"localhost:7280\")))?;\nlet client = RestClient::new(endpoint, ...);","handlingStrategy":"validation","validationCode":"let parsed = url::Url::parse(endpoint).expect(\"valid absolute URL\");\nassert!(matches!(parsed.scheme(), \"http\" | \"https\"));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass absolute http(s):// URLs as the endpoint.","Validate the endpoint config at startup with Url::parse and a scheme check.","Beware values like 'localhost:7280' — without a scheme Url treats 'localhost' as the scheme."],"tags":["rust","url","rest-client","configuration"],"backgroundTag":"invalid-url-format","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}