openai/codex · error · std::io::Error
config defines `[permissions]` profiles but does not set `de
Error message
config defines `[permissions]` profiles but does not set `default_permissions`
What it means
Under the profiles-based permission syntax, defining profiles in `[permissions]` obliges the config to select one. Config computes the effective selection from the `[permissions]` profiles, any default_permissions override, the top-level default_permissions key, and the selection persisted in codex home. If profiles exist, the syntax is not legacy, nothing got selected, and requirements do not force a selection, loading fails with InvalidInput instead of guessing permissions.
Source
Thrown at codex-rs/core/src/config/mod.rs:3386
persisted_permission_profile_id.as_deref()
};
let effective_permission_selection = resolve_effective_permission_selection(
cfg.permissions.as_ref(),
default_permissions_override.as_deref(),
persisted_permission_profile_id,
cfg.default_permissions.as_deref(),
requirements_toml,
&mut startup_warnings,
)?;
if effective_permission_selection.has_profiles()
&& !matches!(
permission_config_syntax,
Some(PermissionConfigSyntax::Legacy)
)
&& effective_permission_selection.selected_profile_id.is_none()
&& !effective_permission_selection.requirements_force_profile_selection
{
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"config defines `[permissions]` profiles but does not set `default_permissions`",
));
}
let memories_config: MemoriesConfig = cfg.memories.clone().unwrap_or_default().into();
let memories_root = memory_root(&codex_home);
let profiles_are_active = effective_permission_selection.profiles_are_active(
default_permissions_override.as_deref(),
permission_config_syntax,
);
let explicit_permission_profile_mode = effective_permission_selection
.persisted_profile_id_was_provided
|| default_permissions_override.is_some()
|| matches!(
permission_config_syntax,
Some(PermissionConfigSyntax::Profiles)View on GitHub (pinned to 339751715c)
Solutions
- Set `default_permissions = "dev"` (naming one of the defined profile ids) in the config that defines the profiles.
- Or pass an explicit permission-profile / default-permissions override when starting Codex.
- Or select a profile once interactively so the choice persists in codex home.
- If the profiles are unused, delete the `[permissions]` profiles block entirely.
Example fix
# before - profiles defined, nothing selected [permissions.profiles.dev] # ...profile body... # after - select the default default_permissions = "dev" [permissions.profiles.dev] # ...profile body...
Defensive patterns
Strategy: validation
Validate before calling
# Pre-flight check before launching codex
import tomllib, sys
cfg = tomllib.load(open("config.toml", "rb"))
perms = cfg.get("permissions", {})
has_profiles = bool(perms.get("profiles"))
selected = cfg.get("default_permissions") or perms.get("default_permissions")
if has_profiles and not selected:
sys.exit("[permissions] profiles require a default_permissions selection") Try / catch
match config_result {
Err(ref e) if e.kind() == std::io::ErrorKind::InvalidInput
&& e.to_string().contains("does not set `default_permissions`") => {
// prompt the user to pick a profile, write default_permissions, retry
}
other => other,
} Prevention
- Always pair a [permissions] profiles block with a default_permissions selector in the same file
- Validate config.toml against core's config.schema.json in CI
- After renaming a profile id, update default_permissions to match
- Ship the complete [permissions] section when sharing configs
When it happens
Trigger: config.toml defines `[permissions]` with profile entries (e.g. `[permissions.profiles.dev]`) but no `default_permissions` is set anywhere, no permission-profile/default-permissions override is passed at startup, and no selection was persisted from a previous interactive pick.
Common situations: Partial migration to permission profiles where the selector was forgotten; copying a `[permissions]` block from docs or teammates minus the default line; fresh machines or cleared codex-home where the persisted selection is missing; renaming a profile without updating the default.
Related errors
- Invalid MCP server name '{server_name}': must match pattern
- failed to parse cloud config fragment {fragment}: {message}
- invalid requirement for MCP server `{server_name}` (set by {
- legacy `profile = "{profile}"` config is no longer supported
- features.multi_agent_v2.max_concurrent_threads_per_session m
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/27cbf35d03f71bd7.
Report an issue: GitHub.