{"record":{"id":"74eb9a5a4b41baa3","repo":"openai/codex","slug":"permissions-profile-profile-name-extends-undef","errorCode":null,"errorMessage":"permissions profile `{profile_name}` extends undefined profile `{parent_profile_name}`","messagePattern":"permissions profile `(.+?)` extends undefined profile `(.+?)`","errorType":"validation","errorClass":"PermissionProfileResolutionError","httpStatus":null,"severity":"error","filePath":"codex-rs/config/src/permissions_toml.rs","lineNumber":125,"sourceCode":"        }\n    }\n}\n\n#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, JsonSchema)]\n#[schemars(deny_unknown_fields)]\npub struct PermissionProfileToml {\n    pub description: Option<String>,\n    pub extends: Option<String>,\n    pub workspace_roots: Option<WorkspaceRootsToml>,\n    pub filesystem: Option<FilesystemPermissionsToml>,\n    pub network: Option<NetworkToml>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Error)]\npub enum PermissionProfileResolutionError {\n    #[error(\"default_permissions refers to undefined profile `{profile_name}`\")]\n    UndefinedProfile { profile_name: String },\n    #[error(\n        \"permissions profile `{profile_name}` extends undefined profile `{parent_profile_name}`\"\n    )]\n    UndefinedParent {\n        profile_name: String,\n        parent_profile_name: String,\n    },\n    #[error(\n        \"permissions profile `{profile_name}` cannot extend unsupported built-in profile `{parent_profile_name}`\"\n    )]\n    UnsupportedBuiltInParent {\n        profile_name: String,\n        parent_profile_name: String,\n    },\n    #[error(\n        \"permissions profile inheritance cycle detected: {}\",\n        cycle.join(\" -> \")\n    )]\n    Cycle { cycle: Vec<String> },","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/config/src/permissions_toml.rs#L107-L143","documentation":"While following a profile's extends chain, resolve_profile could not find the parent: the name is neither a key in the permissions table nor a built-in from the loader closure, and it does not start with ':' (which would yield UnsupportedBuiltInParent instead). Parents merge before children, so one unresolvable link fails the whole profile.","triggerScenarios":"`[permissions.a] extends = \"base\"` with no `[permissions.base]` defined and \"base\" not a built-in — resolving a (or anything extending a) fails.","commonSituations":"Renaming a base profile without updating children's extends references; the parent living in a config layer that is disabled or not loaded (untrusted project directory); plain typos; sharing a permissions file across projects where only some define the base.","solutions":["Define the missing parent `[permissions.<parent>]`","Fix the extends value to the exact name of an existing profile","Drop the extends key if the profile should stand alone"],"exampleFix":"# before\n[permissions.audited]\nextends = \"base\"\n\n[permissions.baseline]\nnetwork = { enabled = false }\n\n# after — match the real parent name\n[permissions.audited]\nextends = \"baseline\"","handlingStrategy":"validation","validationCode":"use codex_config::PermissionsToml;\n\n// Walk the extends chain before resolve_profile.\nfn extends_chain_resolves(\n    permissions: &PermissionsToml,\n    start: &str,\n    is_builtin: impl Fn(&str) -> bool,\n) -> Result<(), String> {\n    let mut seen = std::collections::HashSet::new();\n    let mut name = start.to_string();\n    while seen.insert(name.clone()) {\n        let Some(profile) = permissions.entries.get(&name) else {\n            return Err(format!(\"profile `{name}` is undefined\"));\n        };\n        match profile.extends.as_deref() {\n            Some(parent) => {\n                if !parent.starts_with(':')\n                    && !permissions.entries.contains_key(parent)\n                    && !is_builtin(parent)\n                {\n                    return Err(format!(\"`{name}` extends undefined profile `{parent}\"));\n                }\n                name = parent.to_string();\n            }\n            None => return Ok(()),\n        }\n    }\n    Err(\"inheritance cycle\".to_string())\n}","typeGuard":null,"tryCatchPattern":"match permissions.resolve_profile(name, builtin_lookup) {\n    Err(PermissionProfileResolutionError::UndefinedParent { profile_name, parent_profile_name }) => {\n        // Define [permissions.<parent_profile_name>] or fix the extends\n        // value in [permissions.<profile_name>].\n    }\n    Err(e) => return Err(e.into()),\n    Ok(profile) => { /* ... */ }\n}","preventionTips":["Rename profiles with grep: update every extends reference in the same commit","Keep base profiles in layers that always load (user/system), never in untrusted project config","Spell parent names exactly — profile keys are case-sensitive"],"tags":["permissions","config","profile","inheritance","rust"],"backgroundTag":"undefined-config-reference","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}