{"record":{"id":"2586aac957b96bac","repo":"nautechsystems/nautilus_trader","slug":"error-msg","errorCode":null,"errorMessage":"{error_msg}","messagePattern":"\\{error_msg\\}","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/persistence/src/parquet.rs","lineNumber":995,"sourceCode":"\n    let http_store = builder.build()?;\n    Ok((Arc::new(http_store), path, uri.to_string()))\n}\n\n/// Parses a URL and extracts its path component.\n#[cfg(feature = \"cloud\")]\nfn parse_url_and_path(uri: &str) -> anyhow::Result<(url::Url, String)> {\n    let url = url::Url::parse(uri)?;\n    let path = url.path().trim_start_matches('/').to_string();\n    Ok((url, path))\n}\n\n/// Extracts the host from a URL.\n#[cfg(feature = \"cloud\")]\nfn extract_host(url: &url::Url, error_msg: &str) -> anyhow::Result<String> {\n    url.host_str()\n        .map(ToString::to_string)\n        .ok_or_else(|| anyhow::anyhow!(\"{error_msg}\"))\n}\n\n#[cfg(test)]\nmod tests {\n    #[cfg(feature = \"cloud\")]\n    use ahash::AHashMap;\n    use arrow::{\n        array::Int64Array,\n        datatypes::{DataType, Field, Schema},\n    };\n    use rstest::rstest;\n\n    use super::*;\n\n    #[rstest]\n    fn test_create_object_store_from_path_local() {\n        // Create a temporary directory for testing\n        let temp_dir = std::env::temp_dir().join(\"nautilus_test\");","sourceCodeStart":977,"sourceCodeEnd":1013,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/persistence/src/parquet.rs#L977-L1013","documentation":"extract_host is a shared helper that pulls the host string from a parsed url::Url; if the URL has no host (host_str() returns None), it raises the caller-provided error message. All cloud store builders (S3, GCS, Azure, ABFS) route through it, so this surfaces as 'Invalid ... URI: missing host'.","triggerScenarios":"Calling create_s3_store / create_gcs_store / create_azure_store / create_abfs_store with a URI the url crate parses without a host — e.g. 's3:///bucket/key', relative paths, or schemes like 'file://' passed to a cloud builder.","commonSituations":"Environment/config typo dropping the endpoint host; hand-assembled URIs with triple slashes; using a local path where a cloud URI is expected; overriding endpoint with an empty value.","solutions":["Include a host in the URI: s3://bucket/key, gs://bucket/key, abfss://container@account.dfs.core.windows.net/path","Log the URI string and parsed host before constructing the store","Validate with url::Url::parse(...).host_str().is_some() before calling","Ensure storage options (endpoint_url etc.) are not empty strings that corrupt the URI"],"exampleFix":"// before\nlet uri = \"s3:///nautilus-data\"; // no host\n// after\nlet uri = \"s3://nautilus-data\";","handlingStrategy":"validation","validationCode":"let url = url::Url::parse(uri)?;\nanyhow::ensure!(url.host_str().is_some(), \"URI '{uri}' has no host\");","typeGuard":"fn has_host(s: &str) -> bool {\n    url::Url::parse(s).ok().and_then(|u| u.host_str().map(|_| ())).is_some()\n}","tryCatchPattern":"let store = create_object_store_location_from_path(uri, None)\n    .unwrap_or_else(|e| panic!(\"bad cloud URI '{uri}': {e}\"));","preventionTips":["Include bucket/host in every cloud URI (s3://bucket, gs://bucket)","Avoid triple-slash URIs which drop the host","Keep endpoint overrides non-empty in storage options","Use file:// / local paths only with the local object store, not cloud builders"],"tags":["url","cloud","s3","gcs","azure"],"backgroundTag":"invalid-url-format","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}