Hmbown/CodeWhale · error
agent profile {} may not disable approval_required
Error message
agent profile {} may not disable approval_required What it means
Codewhale loads agent profile TOML files (project .codewhale/agents/*.toml and plugin components) through reject_permission_expansion (crates/tui/src/fleet/profile.rs:422). Workspace and plugin profiles are untrusted for security posture: they may not weaken the human-approval gate. A [permissions] table containing approval_required = false is rejected at load time, exactly like allow_shell = true and trust = true. Permission grants live only in the FleetProfile policy layer, never in profile files.
Source
Thrown at crates/tui/src/fleet/profile.rs:454
),
}
}
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()
);
}
if permissions.approval_required == Some(false) {
bail!(
"agent profile {} may not disable approval_required",
path.display()
);
}
}
Ok(())
}
fn validate_agent_profile_token(path: &Path, field: &str, value: &str) -> Result<()> {
let trimmed = value.trim();
if trimmed.is_empty() {
bail!("agent profile {} {field} cannot be empty", path.display());
}
if trimmed != value || !trimmed.chars().all(is_agent_profile_token_char) {
bail!(
"agent profile {} {field} must be a simple token",
path.display()
);View on GitHub (pinned to 0c42157ee5)
Solutions
- Open the profile file named in the error message and delete approval_required = false from [permissions] (or set it to true)
- Move the permission change to the FleetProfile policy layer or launch-time flags that own grants - profiles can only inherit permissions, never widen them
- For unattended runs, configure the approval policy at the fleet/launch level instead of per profile
Example fix
# before (.codewhale/agents/scout.toml) [permissions] approval_required = false # after [permissions] approval_required = true # or delete the key entirely
Defensive patterns
Strategy: validation
Validate before calling
fn profile_disables_approval(raw: &str) -> bool {
let mut in_permissions = false;
for line in raw.lines() {
let t = line.trim();
if t.starts_with('[') {
in_permissions = t == "[permissions]";
} else if in_permissions && t.starts_with("approval_required") && t.contains("false") {
return true;
}
}
false
}
// run before load_agent_profile_file / roster scans Try / catch
match load_agent_profile_file(&path) {
Ok(profile) => profiles.push(profile),
Err(err) if err.to_string().contains("may not disable approval_required") => {
report_policy_violation(&path); // guide author to policy layer
}
Err(err) => issues.push(format!("{err:#}")),
} Prevention
- Treat [permissions] in profile TOML as read-only: never generate allow_shell, trust, or approval_required=false
- Lint .codewhale/agents/*.toml and plugin profile components in CI with the same rules
- Route every request for fewer approvals through the FleetProfile policy layer, not profile files
When it happens
Trigger: Calling load_agent_profile_file (directly or via the profile-directory scan / plugin component load) on a TOML file whose [permissions] table sets approval_required = false. The check is exact: Some(false) bails; approval_required = true or an omitted key passes.
Common situations: Copying a profile written before this policy existed; trying to make a fleet worker run unattended by disabling approvals in its profile; a plugin shipping profiles that assumed self-approved execution.
Related errors
- agent profile {} may not request allow_shell=true
- agent profile {} may not request trust=true
- agent profile {} {field} cannot be empty
- agent profile {} {field} must be a simple token
- agent profile {} provider cannot be empty
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/99dbedc06b97a5ed.
Report an issue: GitHub.