{"record":{"id":"e494f376d245993e","repo":"nautechsystems/nautilus_trader","slug":"failed-to-parse-object-store-uri-path-e","errorCode":null,"errorMessage":"Failed to parse object store URI {path}: {e}","messagePattern":"Failed to parse object store URI (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/persistence/src/backend/catalog.rs","lineNumber":3052,"sourceCode":"\n    fn object_store_path(&self, path: &str) -> anyhow::Result<String> {\n        let normalized_path = path.replace('\\\\', \"/\");\n\n        if self.is_remote_uri() {\n            if normalized_path.contains(\"://\") {\n                let path_under_root = self.remote_uri_object_path(&normalized_path)?;\n                return Ok(self.path_under_base(&path_under_root));\n            }\n\n            return Ok(self.path_under_base(&normalized_path));\n        }\n\n        Ok(self.path_without_local_base(&normalized_path))\n    }\n\n    fn remote_uri_object_path(&self, path: &str) -> anyhow::Result<String> {\n        let path_url = url::Url::parse(path)\n            .map_err(|e| anyhow::anyhow!(\"Failed to parse object store URI {path}: {e}\"))?;\n        if !is_remote_uri_scheme(path_url.scheme()) {\n            anyhow::bail!(\n                \"URI {path} uses non-remote scheme {} for remote catalog at {}\",\n                path_url.scheme(),\n                self.original_uri,\n            );\n        }\n\n        let catalog_root = remote_store_root_url(&self.original_uri)?;\n        let path_root = remote_store_root_url(path)?;\n        if catalog_root.as_str().trim_end_matches('/') != path_root.as_str().trim_end_matches('/') {\n            anyhow::bail!(\n                \"Cross-store URI {path} (root {}) does not belong to catalog rooted at {} ({})\",\n                path_root.as_str().trim_end_matches('/'),\n                self.original_uri,\n                catalog_root.as_str().trim_end_matches('/'),\n            );\n        }","sourceCodeStart":3034,"sourceCodeEnd":3070,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/persistence/src/backend/catalog.rs#L3034-L3070","documentation":"Raised in `remote_uri_object_path` when the path given to the remote catalog cannot be parsed as a URL by the `url` crate. The remote catalog expects every path to be a well-formed URI (e.g. `s3://bucket/key`); the original parse error is embedded in the message after the offending path.","triggerScenarios":"Calling `object_store_path` (or any path-resolution entry point) on a remote `ParquetDataCatalog` with a string that is not a valid absolute URI — e.g. a plain filesystem path like `/data/catalog/quotes.parquet` or a malformed scheme like `s3:/bucket/key`.","commonSituations":"Constructing the catalog with a remote URI (s3://, gs://, abfs://) but then passing local-style relative paths to query/write methods; typo'd or double/unbalanced slashes in the scheme; path built by string concatenation that dropped the scheme prefix; copy-pasting a path without the URI.","solutions":["Ensure the path passed in is a fully-qualified remote URI including scheme, e.g. `s3://bucket/path/to/file.parquet`.","Check the URI parses standalone (e.g. `url::Url::parse` or a quick manual check) — the embedded `{e}` names the exact parse defect.","Use the catalog's own path-building helpers (`make_path`, `path_without_local_base`) instead of hand-concatenating strings.","If a local path is intended, construct the catalog as a local (non-remote) catalog so `remote_uri_object_path` is not used."],"exampleFix":"// before\nlet path = catalog.object_store_path(\"data/quotes.parquet\")?; // no scheme\n\n// after\nlet path = catalog.object_store_path(\"s3://my-bucket/data/quotes.parquet\")?;","handlingStrategy":"validation","validationCode":"fn ensure_remote_uri(path: &str) -> Result<(), String> {\n    match url::Url::parse(path) {\n        Ok(u) if matches!(u.scheme(), \"s3\" | \"gs\" | \"az\" | \"abfs\" | \"https\" | \"file\") => Ok(()),\n        Ok(u) => Err(format!(\"scheme '{}' not remote-capable\", u.scheme())),\n        Err(e) => Err(format!(\"not a valid URI: {e}\")),\n    }\n}","typeGuard":"fn is_remote_uri(path: &str) -> bool {\n    url::Url::parse(path).map(|u| !u.scheme().is_empty() && path.contains(\"://\")).unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Always pass fully-qualified URIs (scheme://bucket/key) to remote catalog methods.","Build paths with the catalog's make_path/URI helpers instead of string concatenation.","Use a local catalog instance for filesystem paths; reserve remote catalogs for s3://, gs://, etc.","Unit-test path construction with the same URI parser (url::Url::parse) the catalog uses."],"tags":["url","object-store","persistence","config"],"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"}