{"record":{"id":"dc3c32af4cf4f704","repo":"xai-org/x-algorithm","slug":"backend-unavailable","errorCode":null,"errorMessage":"BACKEND_UNAVAILABLE","messagePattern":"BACKEND_UNAVAILABLE","errorType":"error_code","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"phoenix/crates/storage/xai-o2/src/o2_client_builder.rs","lineNumber":78,"sourceCode":"\n    pub fn write_chunk_size_mib(&mut self, _value: usize) -> &mut Self {\n        self\n    }\n\n    pub fn write_chunk_concurrency(&mut self, _value: usize) -> &mut Self {\n        self\n    }\n\n    pub fn max_concurrent_write_requests(&mut self, _value: usize) -> &mut Self {\n        self\n    }\n\n    pub fn trace_always(&mut self, _value: bool) -> &mut Self {\n        self\n    }\n\n    pub fn build(&self) -> Result<Arc<dyn BaseO2Client>> {\n        Err(anyhow::anyhow!(BACKEND_UNAVAILABLE))\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn build_fails_loudly_after_full_configuration() {\n        let mut builder = O2ClientBuilder::default();\n        builder\n            .endpoint(\"http://localhost:9000\")\n            .bucket(\"some-bucket\")\n            .prefix(\"\")\n            .write_chunk_size_mib(8)\n            .write_chunk_concurrency(16)\n            .max_concurrent_write_requests(64)\n            .retry_max_times(6)","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/phoenix/crates/storage/xai-o2/src/o2_client_builder.rs#L60-L96","documentation":"Thrown by O2ClientBuilder::build, which unconditionally returns Err(BACKEND_UNAVAILABLE). This builder is a stub/placeholder implementation: no matter how it's configured (trace_always and all setters are no-ops), build() always fails, signalling that the O2 storage backend is not available in this build.","triggerScenarios":"Any code path that constructs an O2 client via this builder and calls build() — always fails immediately, including in tests (build_fails_loudly_after_full_configuration, build_error_converts_to_boxed_std_error) that assert this exact behavior.","commonSituations":"Feature flags disabling the real O2 backend; using a stub crate variant in a build where O2 isn't linked; accidentally wiring the stub builder in production config; version of the crate where O2 support isn't compiled in.","solutions":["Determine why the stub builder is being used — check feature flags / cfg attributes selecting it over the real implementation","If O2 should be available, switch to the real builder (e.g. build_xai_o2_client) or enable the required cargo feature","If O2 is intentionally unavailable, guard callers with a fallback storage backend instead of calling build()","Consult crate docs/maintainers for the flag that enables the real backend"],"exampleFix":"// before\nlet client: Arc<dyn BaseO2Client> = O2ClientBuilder::new().endpoint(url).build()?;\n\n// after\nlet client: Arc<dyn BaseO2Client> = build_xai_o2_client(cfg).await?; // real builder, not the stub","handlingStrategy":"fallback","validationCode":"assert the builder being used is the real implementation (e.g. cfg/feature check) before build()","typeGuard":null,"tryCatchPattern":"match builder.build() { Err(e) if e.to_string().contains(\"BACKEND_UNAVAILABLE\") => use_fallback_storage(), r => r? }","preventionTips":["Never wire the stub builder in production configs","Gate stubs behind cfg(test) or explicit dev features","Integration-test that prod config builds a real O2 client"],"tags":["stub","backend-unavailable","feature-flag","o2","rust"],"backgroundTag":"backend-unavailable","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}