Hmbown/CodeWhale · error

Failed to update setting: invalid permission posture

Error message

Failed to update setting: invalid permission posture '{value}'. Expected: ask, auto-review, or full-access.

What it means

Settings::set normalizes the `permission_posture`/`permissions` value via normalize_permission_posture; when it returns None the setter bails. Accepted values are ask, auto-review, and full-access. The posture drives how agent tool calls are gated, so an unknown value is refused rather than silently downgraded.

Solutions

  1. Use exactly ask, auto-review, or full-access.
  2. Check normalize_permission_posture in settings.rs for accepted aliases/casing.
  3. If you intended legacy yolo behavior, that maps to full-access posture (plus sandbox choices).

Example fix

// before
settings.set("permission_posture", "yolo")?;
// after
settings.set("permission_posture", "full-access")?;
Defensive patterns

Strategy: validation

Validate before calling

fn valid_posture(v: &str) -> bool {
    matches!(v.trim().to_ascii_lowercase().as_str(), "ask" | "auto-review" | "full-access")
}

Try / catch

match settings.set("permission_posture", value) {
    Err(e) if e.to_string().contains("invalid permission posture") => eprintln!("expected ask, auto-review, or full-access"),
    r => r?,
}

Prevention

When it happens

Trigger: Settings::set("permission_posture", v) or set("permissions", v) where the normalizer yields None — e.g. `permissions yolo`, `permissions full`, `permissions Full-Access` if normalization is case-sensitive.

Common situations: Users migrating from the old `yolo` mode, abbreviating (`auto`, `autoapprove`), or hand-writing the value in config scripts with wrong hyphenation/casing.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at crates/tui/src/settings.rs:1756

                anyhow::bail!(
                    "Model defaults belong to config.toml. Use /model and choose Remember as my default, or /config model <id> --save."
                );
            }
            "reasoning_effort" | "effort" => {
                self.reasoning_effort = normalize_reasoning_effort_setting(value)?;
            }
            "permission_posture" | "permissions" => {
                self.permission_posture = normalize_permission_posture(value);
                if self.permission_posture.is_none() {
                    anyhow::bail!(
                        "Failed to update setting: invalid permission posture '{value}'. Expected: ask, auto-review, or full-access."
                    );
                }
            }
            "sandbox_mode" | "sandbox" | "filesystem_sandbox" => {
                self.sandbox_mode = normalize_sandbox_mode(value);
                if self.sandbox_mode.is_none() {
                    anyhow::bail!(
                        "Failed to update setting: invalid sandbox_mode '{value}'. Expected: read-only, workspace-write, danger-full-access, or external-sandbox."
                    );
                }
            }
            _ => {
                anyhow::bail!("Failed to update setting: unknown setting '{key}'.");
            }
        }
        if let Some(canonical) = canonical {
            self.provenance
                .insert(canonical.to_string(), Layer::SessionOverride);
        }
        Ok(())
    }

    /// Apply a named settings preset (#3478).
    ///
    /// Presets are the first bundled-settings mechanism: a single name applies a

View on GitHub (pinned to 73e0f67d83)