{"record":{"id":"d04537fc72bade17","repo":"Hmbown/CodeWhale","slug":"refusing-base-url-display-base-url-only-https","errorCode":null,"errorMessage":"Refusing base URL '{display_base_url}': only HTTPS (or explicitly allowed HTTP) URLs are supported.","messagePattern":"Refusing base URL '(.+?)': only HTTPS \\(or explicitly allowed HTTP\\) URLs are supported\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/client.rs","lineNumber":684,"sourceCode":"        logging::warn(format!(\n            \"Using insecure HTTP base URL because {ALLOW_INSECURE_HTTP_ENV} is set\"\n        ));\n        return Ok(());\n    }\n\n    if base_url.starts_with(\"http://\") {\n        anyhow::bail!(\n            \"Refusing insecure base URL '{display_base_url}'.\\n\\\n             \\n\\\n             Loopback hosts (localhost, 127.0.0.1, [::1]) are auto-allowed.\\n\\\n             For other trusted local hosts (LAN, llama.cpp on a private IP, etc.)\\n\\\n             set the env var `{ALLOW_INSECURE_HTTP_ENV}=1` in the shell that runs codewhale and re-run.\\n\\\n             \\n\\\n             Example: `{ALLOW_INSECURE_HTTP_ENV}=1 codewhale` (note the underscores).\",\n        );\n    }\n\n    anyhow::bail!(\n        \"Refusing base URL '{display_base_url}': only HTTPS (or explicitly allowed HTTP) URLs are supported.\",\n    )\n}\n\npub(crate) fn redact_url_for_display(url: &str) -> String {\n    let Ok(mut parsed) = reqwest::Url::parse(url) else {\n        return url.to_string();\n    };\n    if !parsed.username().is_empty() || parsed.password().is_some() {\n        let _ = parsed.set_username(\"***\");\n        let _ = parsed.set_password(Some(\"***\"));\n    }\n    if parsed.query().is_none() {\n        return parsed.to_string();\n    }\n    let pairs: Vec<(String, String)> = parsed\n        .query_pairs()\n        .map(|(key, value)| {","sourceCodeStart":666,"sourceCodeEnd":702,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/client.rs#L666-L702","documentation":"The terminal branch of `validate_base_url_security`: the base URL scheme is neither `https://` nor `http://` (the http:// branches were already handled above), so the client refuses it outright. This catches URLs with no scheme at all and non-HTTP schemes; the scheme test is a literal case-sensitive prefix match, so an uppercase `HTTP://` or `HTTPS://` also lands here.","triggerScenarios":"A `base_url` like `api.example.com/v1` (missing scheme), `ftp://host`, `ws://host:8080`, `HTTPS://api.example.com` (uppercase), or a URL with leading whitespace before the scheme. Any of these fall through both `starts_with(\"https://\")` and `starts_with(\"http://\")` checks and hit the final bail.","commonSituations":"Copying a hostname from docs without the scheme; assuming the client will add `https://` automatically; pasting a websocket URL because the provider docs show `wss://`; editors auto-capitalizing or inserting a smart quote/BOM before the URL.","solutions":["Write the full absolute URL with a lowercase scheme: `base_url = \"https://api.example.com/v1\"`.","If you intended plain HTTP to a local server, use `http://localhost...` or set `CODEWHALE_ALLOW_INSECURE_HTTP=1` with an `http://` scheme — but the scheme must still be lowercase `http://`.","Check the value for leading/trailing whitespace, BOM, or uppercase scheme characters in the config file."],"exampleFix":"# before\nbase_url = \"api.example.com/v1\"\n# after\nbase_url = \"https://api.example.com/v1\"","handlingStrategy":"validation","validationCode":"fn has_supported_scheme(base_url: &str) -> bool {\n    let u = base_url.trim();\n    u.starts_with(\"https://\") || u.starts_with(\"http://\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write provider base URLs as absolute URLs with a lowercase scheme (`https://host/path`).","Validate the URL at config-load time with `reqwest::Url::parse` and reject non-http(s) schemes with a clear message.","Trim whitespace and strip BOM when reading base_url from user-supplied config."],"tags":["security","configuration","base-url","url-parsing","validation"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}