Hmbown/CodeWhale · error · anyhow::Error
Invalid sandbox_mode '{mode}': expected read-only, workspace
Error message
Invalid sandbox_mode '{mode}': expected read-only, workspace-write, danger-full-access, or external-sandbox. What it means
Config::validate() restricts sandbox_mode to read-only, workspace-write, danger-full-access, or external-sandbox (trim + lowercase normalized). This is a security-sensitive enum: a misspelled mode must fail closed rather than silently default to a weaker sandbox.
Source
Thrown at crates/tui/src/config.rs:4438
) {
anyhow::bail!(
"Invalid approval_policy '{policy}': expected on-request, untrusted, never, auto, or suggest."
);
}
}
if let Some(v) = self.verbosity.as_deref() {
let normalized = v.trim().to_ascii_lowercase();
if !matches!(normalized.as_str(), "normal" | "concise") {
anyhow::bail!("Invalid verbosity '{v}': expected normal or concise.");
}
}
if let Some(mode) = self.sandbox_mode.as_deref() {
let normalized = mode.trim().to_ascii_lowercase();
if !matches!(
normalized.as_str(),
"read-only" | "workspace-write" | "danger-full-access" | "external-sandbox"
) {
anyhow::bail!(
"Invalid sandbox_mode '{mode}': expected read-only, workspace-write, danger-full-access, or external-sandbox."
);
}
}
if let Some(tui) = &self.tui
&& let Some(mode) = tui.alternate_screen.as_deref()
{
let mode = mode.to_ascii_lowercase();
if !matches!(mode.as_str(), "auto" | "always" | "never") {
anyhow::bail!(
"Invalid tui.alternate_screen '{mode}': expected auto, always, or never."
);
}
}
if let Some(auto_review) = &self.auto_review {
auto_review.validate()?;
}
if let Some(providers) = &self.providers {View on GitHub (pinned to 8880682c63)
Solutions
- Use exactly one of: read-only, workspace-write, danger-full-access, external-sandbox.
- Pick read-only or workspace-write unless you explicitly need danger-full-access.
- Re-validate the config after the edit.
Example fix
# before sandbox_mode = "full-access" # after sandbox_mode = "danger-full-access"
Defensive patterns
Strategy: validation
Validate before calling
fn sandbox_mode_is_valid(raw: &str) -> bool {
matches!(
raw.trim().to_ascii_lowercase().as_str(),
"read-only" | "workspace-write" | "danger-full-access" | "external-sandbox"
)
}
if let Some(m) = &config.sandbox_mode {
anyhow::ensure!(sandbox_mode_is_valid(m), "unknown sandbox_mode");
} Type guard
fn is_valid_sandbox_mode(raw: &str) -> bool {
matches!(
raw.trim().to_ascii_lowercase().as_str(),
"read-only" | "workspace-write" | "danger-full-access" | "external-sandbox"
)
} Try / catch
if let Err(e) = config.validate() {
let msg = e.to_string();
if msg.starts_with("Invalid sandbox_mode") {
// fail closed: never guess a mode; prompt the user to pick from the allowed list
return Err(e);
}
} Prevention
- Treat sandbox_mode typos as security incidents, not cosmetic ones — fix before running.
- Default to read-only/workspace-write; require an explicit review to reach danger-full-access.
- CI-lint the value against the four-element allowlist.
When it happens
Trigger: Typing sandbox_mode = "write", "full", "none", "full-access", or "danger-full" in config.toml; using a value from an older release whose vocabulary differed.
Common situations: Muscle-memory abbreviations from other tools' sandbox flags; hardening review copies a half-remembered mode name; config synced from a version with a different enum.
Related errors
- Invalid default_text_model '{model}' for provider '{}': expe
- Invalid approval_policy '{policy}': expected on-request, unt
- Invalid verbosity '{v}': expected normal or concise.
- Invalid tui.alternate_screen '{mode}': expected auto, always
- unavailable credential
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/2ba669a2777f00a0.
Report an issue: GitHub.