{"record":{"id":"279e5c814d90d392","repo":"Hmbown/CodeWhale","slug":"invalid-approval-policy-policy-expected-on-re","errorCode":null,"errorMessage":"Invalid approval_policy '{policy}': expected on-request, untrusted, never, auto, or suggest.","messagePattern":"Invalid approval_policy '(.+?)': expected on-request, untrusted, never, auto, or suggest\\.","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/config.rs","lineNumber":4421,"sourceCode":"            let provider = self.api_provider();\n            let known = model_completion_names_for_provider(provider);\n            let hint = if known.is_empty() {\n                String::new()\n            } else {\n                format!(\" (for example: {})\", known.join(\", \"))\n            };\n            anyhow::bail!(\n                \"Invalid default_text_model '{model}' for provider '{}': expected auto or a model ID this provider serves{hint}.\",\n                provider.as_str()\n            );\n        }\n        if let Some(policy) = self.approval_policy.as_deref() {\n            let normalized = policy.trim().to_ascii_lowercase();\n            if !matches!(\n                normalized.as_str(),\n                \"on-request\" | \"untrusted\" | \"never\" | \"auto\" | \"suggest\"\n            ) {\n                anyhow::bail!(\n                    \"Invalid approval_policy '{policy}': expected on-request, untrusted, never, auto, or suggest.\"\n                );\n            }\n        }\n        if let Some(v) = self.verbosity.as_deref() {\n            let normalized = v.trim().to_ascii_lowercase();\n            if !matches!(normalized.as_str(), \"normal\" | \"concise\") {\n                anyhow::bail!(\"Invalid verbosity '{v}': expected normal or concise.\");\n            }\n        }\n        if let Some(mode) = self.sandbox_mode.as_deref() {\n            let normalized = mode.trim().to_ascii_lowercase();\n            if !matches!(\n                normalized.as_str(),\n                \"read-only\" | \"workspace-write\" | \"danger-full-access\" | \"external-sandbox\"\n            ) {\n                anyhow::bail!(\n                    \"Invalid sandbox_mode '{mode}': expected read-only, workspace-write, danger-full-access, or external-sandbox.\"","sourceCodeStart":4403,"sourceCodeEnd":4439,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/config.rs#L4403-L4439","documentation":"Config::validate() normalizes approval_policy (trim + ASCII lowercase) and requires one of on-request, untrusted, never, auto, or suggest. Any other string fails validation at startup with this message. Case and surrounding whitespace are tolerated; the keyword itself must match exactly.","triggerScenarios":"Writing approval_policy = \"on_request\" (underscore instead of hyphen), \"always\", \"ask\", or \"when-needed\" in config.toml; passing a policy string copied from a different tool's config.","commonSituations":"Migrating configs from other CLI agents whose policy vocabularies differ; hyphen/underscore confusion; abbreviations like 'req' typed from memory.","solutions":["Set approval_policy to one of: on-request, untrusted, never, auto, suggest (hyphenated, lowercase).","Remove the key entirely if the built-in default is acceptable.","Check for a duplicate approval_policy key elsewhere in the TOML overriding your fix."],"exampleFix":"# before\napproval_policy = \"on_request\"\n\n# after\napproval_policy = \"on-request\"","handlingStrategy":"validation","validationCode":"const APPROVAL_POLICIES: &[&str] = &[\"on-request\", \"untrusted\", \"never\", \"auto\", \"suggest\"];\n\nfn approval_policy_is_valid(raw: &str) -> bool {\n    APPROVAL_POLICIES.contains(&raw.trim().to_ascii_lowercase().as_str())\n}\n\nif let Some(p) = &config.approval_policy {\n    anyhow::ensure!(approval_policy_is_valid(p), \"bad approval_policy\");\n}","typeGuard":"fn is_valid_approval_policy(raw: &str) -> bool {\n    matches!(\n        raw.trim().to_ascii_lowercase().as_str(),\n        \"on-request\" | \"untrusted\" | \"never\" | \"auto\" | \"suggest\"\n    )\n}","tryCatchPattern":"if let Err(e) = config.validate() {\n    if let Some(rest) = e.to_string().strip_prefix(\"Invalid approval_policy \") {\n        // `rest` names the offending value; offer the allowed list and re-validate\n    } else {\n        return Err(e);\n    }\n}","preventionTips":["Use hyphens, not underscores, in policy keywords.","Generate config from constants/enums in tooling instead of hand-typed strings.","Lint committed config.toml files against the allowed vocabulary in CI."],"tags":["rust","config","toml","validation","approval-policy"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}