xai-org/x-algorithm · critical · anyhow::Error

BACKEND_UNAVAILABLE

Error message

BACKEND_UNAVAILABLE

What it means

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.

Source

Thrown at phoenix/crates/storage/xai-o2/src/o2_client_builder.rs:78

    pub fn write_chunk_size_mib(&mut self, _value: usize) -> &mut Self {
        self
    }

    pub fn write_chunk_concurrency(&mut self, _value: usize) -> &mut Self {
        self
    }

    pub fn max_concurrent_write_requests(&mut self, _value: usize) -> &mut Self {
        self
    }

    pub fn trace_always(&mut self, _value: bool) -> &mut Self {
        self
    }

    pub fn build(&self) -> Result<Arc<dyn BaseO2Client>> {
        Err(anyhow::anyhow!(BACKEND_UNAVAILABLE))
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn build_fails_loudly_after_full_configuration() {
        let mut builder = O2ClientBuilder::default();
        builder
            .endpoint("http://localhost:9000")
            .bucket("some-bucket")
            .prefix("")
            .write_chunk_size_mib(8)
            .write_chunk_concurrency(16)
            .max_concurrent_write_requests(64)
            .retry_max_times(6)

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Determine why the stub builder is being used — check feature flags / cfg attributes selecting it over the real implementation
  2. If O2 should be available, switch to the real builder (e.g. build_xai_o2_client) or enable the required cargo feature
  3. If O2 is intentionally unavailable, guard callers with a fallback storage backend instead of calling build()
  4. Consult crate docs/maintainers for the flag that enables the real backend

Example fix

// before
let client: Arc<dyn BaseO2Client> = O2ClientBuilder::new().endpoint(url).build()?;

// after
let client: Arc<dyn BaseO2Client> = build_xai_o2_client(cfg).await?; // real builder, not the stub
Defensive patterns

Strategy: fallback

Validate before calling

assert the builder being used is the real implementation (e.g. cfg/feature check) before build()

Try / catch

match builder.build() { Err(e) if e.to_string().contains("BACKEND_UNAVAILABLE") => use_fallback_storage(), r => r? }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/dc3c32af4cf4f704. Report an issue: GitHub.