Hmbown/CodeWhale · error

agent profile {} tools.posture={other:?} would widen permiss

Error message

agent profile {} tools.posture={other:?} would widen permissions; use FleetProfile policy for grants

What it means

reject_permission_expansion only accepts tools.posture values "read-only", "readonly", or "read_only" in agent profile files; any other posture would widen what the profile may do. Granting beyond read-only is reserved to the FleetProfile policy layer, so an expansive posture in a TOML profile is rejected at load time.

Source

Thrown at crates/tui/src/fleet/profile.rs:433

pub(crate) fn canonical_public_role_name(role: &str) -> String {
    match role.trim().to_ascii_lowercase().as_str() {
        "oracle" | "advisor" => "consultant".to_string(),
        _ => role.to_string(),
    }
}

fn reject_permission_expansion(
    path: &Path,
    tools: Option<&AgentProfileTools>,
    permissions: Option<&AgentProfilePermissionsToml>,
) -> Result<()> {
    if let Some(posture) = tools
        .and_then(|tools| tools.posture.as_deref())
        .and_then(trimmed_non_empty)
    {
        match posture {
            "read-only" | "readonly" | "read_only" => {}
            other => bail!(
                "agent profile {} tools.posture={other:?} would widen permissions; use FleetProfile policy for grants",
                path.display()
            ),
        }
    }

    if let Some(permissions) = permissions {
        if permissions.allow_shell.unwrap_or(false) {
            bail!(
                "agent profile {} may not request allow_shell=true",
                path.display()
            );
        }
        if permissions.trust.unwrap_or(false) {
            bail!(
                "agent profile {} may not request trust=true",
                path.display()
            );

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Set tools.posture to "read-only" (or remove the key) in the profile TOML
  2. Move any real grants into the FleetProfile policy configuration where they are auditable
  3. Check exact spelling: only the three read-only variants are accepted

Example fix

# before
[tools]
posture = "full"

# after
[tools]
posture = "read-only"
# grants live in the FleetProfile policy, not here
Defensive patterns

Strategy: validation

Validate before calling

fn posture_is_allowed(posture: &str) -> bool {
    matches!(posture, "read-only" | "readonly" | "read_only")
}

// lint profile files before the loader does:
assert!(posture_is_allowed(&profile.tools.posture.unwrap_or_default()));

Try / catch

if let Err(err) = load_agent_profile_file(&path) {
    if err.to_string().contains("would widen permissions") {
        eprintln!("set tools.posture = \"read-only\"; grant via FleetProfile policy instead");
    }
    return Err(err.into());
}

Prevention

When it happens

Trigger: An agent profile TOML with tools.posture = "full", "write", "interactive", or any non-read-only spelling (e.g. "read only" with a space, "Read-Only").

Common situations: Porting a profile from another tool where postures like 'full-access' exist; attempting to grant shell/write via the profile instead of the fleet policy; typos in the posture string.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/3d4797b7662cbf87. Report an issue: GitHub.