{"record":{"id":"04a3ab732b04a653","repo":"Hmbown/CodeWhale","slug":"unsupported-bundle-url-scheme-use-https","errorCode":null,"errorMessage":"unsupported bundle URL scheme; use https","messagePattern":"unsupported bundle URL scheme; use https","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/config_bundles.rs","lineNumber":816,"sourceCode":"        );\n    }\n\n    // Read at most MAX_BUNDLE_BYTES + 1 so an oversize body is detected\n    // rather than silently truncated.\n    let mut buffer = Vec::new();\n    let body = response;\n    body.take(MAX_BUNDLE_BYTES + 1)\n        .read_to_end(&mut buffer)\n        .map_err(|_| anyhow!(\"reading remote bundle failed\"))?;\n    if buffer.len() as u64 > MAX_BUNDLE_BYTES {\n        bail!(\"remote bundle exceeds the {MAX_BUNDLE_BYTES} byte limit; refused\");\n    }\n    Ok(buffer)\n}\n\nfn validate_bundle_url(url: &reqwest::Url) -> Result<()> {\n    if !matches!(url.scheme(), \"http\" | \"https\") {\n        bail!(\"unsupported bundle URL scheme; use https\");\n    }\n    if !url.username().is_empty() || url.password().is_some() {\n        bail!(\"bundle URLs may not include credentials\");\n    }\n    let host = url.host_str().context(\"bundle URL must include a host\")?;\n    match url.scheme() {\n        \"https\" => Ok(()),\n        \"http\" if is_loopback_bundle_host(host) => Ok(()),\n        \"http\" => bail!(\"plain http is only allowed for loopback hosts; use https\"),\n        _ => unreachable!(\"scheme was validated above\"),\n    }\n}\n\nfn validate_bundle_redirect(initial_scheme: &str, next_url: &reqwest::Url) -> Result<()> {\n    validate_bundle_url(next_url)?;\n    if next_url.scheme() != initial_scheme {\n        bail!(\"bundle redirects may not change URL scheme\");\n    }","sourceCodeStart":798,"sourceCodeEnd":834,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/cli/src/config_bundles.rs#L798-L834","documentation":"validate_bundle_url rejects bundle URLs whose scheme is not http or https. The library only supports fetching config bundles over web schemes; schemes like file://, ftp://, or data:// are refused before any request is made, since the bundle fetcher is a network client (reqwest) and other schemes are not part of its threat model. The message points the user at https as the intended scheme.","triggerScenarios":"Passing a URL with a non-web scheme to bundle fetch/validate paths — e.g. `codewhale bundle add file:///etc/config.toml`, an ftp:// URL, or a URL missing a scheme so it fails to parse into a web URL — from fetch_bundle or validate_bundle_redirect.","commonSituations":"Pasting a local file path instead of a hosted bundle URL; copying an internal mirror link that uses ftp or a custom proxy scheme; typos like `htp://` that leave the URL schemeless after parsing; scripts interpolating schemeless hostnames.","solutions":["Use an https:// URL for the bundle (e.g. https://example.com/bundle.toml).","If the bundle is a local file, distribute it via a local HTTP server (http://127.0.0.1:PORT is allowed for loopback) instead of file://.","Fix the URL typo so the scheme parses as http or https.","Host the bundle on an internal HTTPS mirror reachable from your network."],"exampleFix":"// before\ncodewhale bundle add file:///srv/team-config.toml\n// after\ncodewhale bundle add https://config.internal.example/team-config.toml","handlingStrategy":"validation","validationCode":"let url = reqwest::Url::parse(input)?;\nif !matches!(url.scheme(), \"http\" | \"https\") {\n    return Err(anyhow!(\"bundle URL must use http(s), got: {}\", url.scheme()));\n}","typeGuard":"fn is_web_url(u: &reqwest::Url) -> bool {\n    matches!(u.scheme(), \"http\" | \"https\")\n}","tryCatchPattern":null,"preventionTips":["Always prefix bundle locations with https:// in scripts and docs.","Never pass local file paths where a URL is expected; serve locally over loopback http instead.","Validate URLs with a parser (reqwest::Url::parse) before storing them in config."],"tags":["cli","url-validation","config-bundles","network"],"backgroundTag":"invalid-url-format","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}