Hmbown/CodeWhale · error

Unsupported sandbox_backend setting. Choose opensandbox, or…

Error message

Unsupported sandbox_backend setting. Choose opensandbox, or explicitly set none for local execution.

What it means

SandboxBackend::exec is called on UnsupportedBackend, a placeholder backend returned when the configured sandbox_backend is neither a real backend nor the explicit `none` value. It always fails, so any command routed through the sandbox during exec aborts. The message tells you the setting was unrecognized and that `none` is the opt-out for local execution.

Solutions

  1. Set sandbox_backend to `opensandbox` in your config if you want remote sandboxed execution.
  2. Set sandbox_backend to `none` explicitly to run locally without a sandbox.
  3. Check for typos and case: the accepted values are lowercase `opensandbox` and `none`.
  4. If this came from a version upgrade, consult the current backend list in crates/tui/src/sandbox/backend.rs and migrate the old value.

Example fix

// before (config)
sandbox_backend = "docker"
// after
sandbox_backend = "opensandbox"  // or "none" for local execution
Defensive patterns

Strategy: validation

Validate before calling

const VALID_BACKENDS: [&str; 2] = ["opensandbox", "none"];
fn ensure_sandbox_backend(v: &str) -> Result<(), String> {
    if VALID_BACKENDS.contains(&v.trim().to_ascii_lowercase().as_str()) { Ok(()) } else {
        Err(format!("sandbox_backend must be opensandbox or none, got '{v}'"))
    }
}

Type guard

fn is_valid_sandbox_backend(v: &str) -> bool {
    matches!(v.trim().to_ascii_lowercase().as_str(), "opensandbox" | "none")
}

Prevention

When it happens

Trigger: Config has `sandbox_backend` set to a value other than `opensandbox` or `none`, and then the exec path calls UnsupportedBackend::exec(cmd, env).

Common situations: Typo in a config file (e.g. `sandbox_backend = "OpenSandbox"` or `"docker"`); copying a config from another project or an older version whose backend names changed; an unset-but-not-empty value written by a script.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/0df1583149ec6a30. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/sandbox/backend.rs:112

                .unwrap_or_else(|| "http://localhost:8080".to_string());
            let api_key = config.sandbox_api_key.clone();
            let backend = super::opensandbox::OpenSandboxBackend::new(base_url, api_key, 30)?;
            Ok(Some(Box::new(backend)))
        }
    }
}

/// A configured execution boundary that is no longer supported. Keep it present
/// in the tool context so every shell call is refused instead of running locally.
struct UnsupportedBackend;

#[async_trait]
impl SandboxBackend for UnsupportedBackend {
    fn kind(&self) -> SandboxKind {
        SandboxKind::Unsupported
    }
    async fn exec(&self, _cmd: &str, _env: &HashMap<String, String>) -> Result<SandboxOutput> {
        anyhow::bail!(
            "Unsupported sandbox_backend setting. Choose opensandbox, or explicitly set none for local execution."
        )
    }
}

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

    #[tokio::test]
    async fn unsupported_backend_refuses_execution_instead_of_falling_back_to_local() {
        for name in ["shannon", "shannonnet", "shannon-net", "levee", "unknown"] {
            let config = Config {
                sandbox_backend: Some(name.into()),
                ..Config::default()
            };
            let backend = create_backend(&config)
                .unwrap()

View on GitHub (pinned to 73e0f67d83)