{"record":{"id":"a9699b9393aa21cd","repo":"xai-org/x-algorithm","slug":"failed-to-check-object-existence","errorCode":null,"errorMessage":"Failed to check object existence: {}","messagePattern":"Failed to check object existence: (.+?)","errorType":"error_code","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"thunder/o2/mod.rs","lineNumber":116,"sourceCode":"        let path = self.full_path(key);\n        let result = self\n            .store\n            .get(&path)\n            .await\n            .with_context(|| format!(\"Failed to get object: {}\", path))?;\n        let bytes = result\n            .bytes()\n            .await\n            .with_context(|| format!(\"Failed to read object bytes: {}\", path))?;\n        Ok(bytes)\n    }\n\n    pub async fn exists(&self, key: &str) -> Result<bool> {\n        let path = self.full_path(key);\n        match self.store.head(&path).await {\n            Ok(_) => Ok(true),\n            Err(object_store::Error::NotFound { .. }) => Ok(false),\n            Err(e) => Err(anyhow!(\"Failed to check object existence: {}\", e)),\n        }\n    }\n\n    pub async fn delete(&self, key: &str) -> Result<()> {\n        let path = self.full_path(key);\n        self.store\n            .delete(&path)\n            .await\n            .with_context(|| format!(\"Failed to delete object: {}\", path))?;\n        Ok(())\n    }\n\n    pub async fn list(&self, key_prefix: &str) -> Result<Vec<String>> {\n        let path = self.full_path(key_prefix);\n        let prefix_str = format!(\"{}/\", self.prefix);\n\n        let objects: Vec<_> = self\n            .store","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/thunder/o2/mod.rs#L98-L134","documentation":"Raised in the O2 wrapper's exists() when store.head(path) fails with an error other than NotFound. head() is being used to test object existence, so any non-NotFound failure (auth, network, malformed path, permission) surfaces as this generic message.","triggerScenarios":"Calling exists(key) when the object store returns an error on HEAD: invalid credentials, bucket not accessible, DNS/network failure to S3/GCS/Azure, or an invalid object path produced by full_path(key).","commonSituations":"Missing/expired cloud credentials (AWS keys, GCP SA); wrong bucket or region in the store URL; network egress blocked from the container; key strings with characters that break path encoding.","solutions":["Check credentials and permissions for the bucket/prefix used by full_path(key)","Print and validate the fully-qualified path (full_path output) for malformed keys","Retry once with backoff for transient network errors before surfacing","Verify the object store URL scheme/bucket config (region, endpoint) matches the environment"],"exampleFix":"// before\nif store.exists(key).await? { ... }\n\n// after\nlet path = format_full_path(key);\ntracing::debug!(\"HEAD {path}\");\nmatch store.exists(key).await {\n    Ok(true) => { /* proceed */ }\n    Ok(false) => { /* missing */ }\n    Err(e) if is_transient(&e) => { /* retry once */ }\n    Err(e) => return Err(anyhow!(\"exists({path}) failed: {e}\")),\n}","handlingStrategy":"retry","validationCode":"// validate key before calling exists: no leading '/', no '..'; preflight store credentials","typeGuard":null,"tryCatchPattern":"match store.exists(key).await { Err(e) if is_transient(&e) => retry_once(...).await, r => r }","preventionTips":["Keep object-store creds fresh and scoped to the bucket","Wrap HEAD failures with path context for debuggability","Add retry-with-jitter at the storage adapter layer"],"tags":["object-store","s3","head-request","credentials","rust"],"backgroundTag":"object-store-head-failed","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}