openai/codex · error
approval_policy = "untrusted" is no longer supported; remove
Error message
approval_policy = "untrusted" is no longer supported; remove this setting
What it means
Part of post-consolidation validation: tokio::fs::metadata follows links, so the ensure! fires when MEMORY.md exists but is not a regular file — typically a directory or a symlink to one (codex-rs/memories/write/src/workspace.rs:65). The validator refuses to bless a tree whose primary memory artifact has the wrong file type; the read itself is wrapped with a 'read consolidated memory artifact' context.
Source
Thrown at codex-rs/app-server/src/config_manager_service.rs:741
for item in items {
array.push(toml_value_to_value(item)?);
}
Ok(toml_edit::Value::Array(array))
}
TomlValue::Table(table) => {
let mut inline = toml_edit::InlineTable::new();
for (key, val) in table {
inline.insert(key, toml_value_to_value(val)?);
}
Ok(toml_edit::Value::InlineTable(inline))
}
}
}
fn validate_config(value: &TomlValue) -> anyhow::Result<()> {
let config: ConfigToml = value.clone().try_into()?;
if config.approval_policy == Some(AskForApproval::UnlessTrusted) {
anyhow::bail!(
"approval_policy = \"untrusted\" is no longer supported; remove this setting"
);
}
Ok(())
}
fn paths_match(expected: impl AsRef<Path>, provided: impl AsRef<Path>) -> bool {
path_utils::paths_match_after_normalization(expected, provided)
}
fn value_at_path<'a>(root: &'a TomlValue, segments: &[String]) -> Option<&'a TomlValue> {
let mut current = root;
for segment in segments {
match current {
TomlValue::Table(table) => {
current = table.get(segment)?;
}
TomlValue::Array(items) => {View on GitHub (pinned to 339751715c)
Solutions
- Inspect the entry (ls -l <root>/MEMORY.md) and remove the offending directory or link.
- Re-run consolidation so MEMORY.md is regenerated as a regular file.
- Exclude the memories root from tools that convert files into directories or links.
Example fix
# before ~/.codex/memories/MEMORY.md/ # accidentally a directory # after rm -r ~/.codex/memories/MEMORY.md && codex memories consolidate
Defensive patterns
Strategy: validation
Validate before calling
async fn memory_md_is_file(root: &std::path::Path) -> bool {
tokio::fs::metadata(root.join("MEMORY.md"))
.await
.map(|m| m.is_file())
.unwrap_or(false)
} Try / catch
if let Err(e) = validate_consolidation_artifacts(root).await {
if e.to_string().contains("is not a file") {
// remove the offending directory/symlink at MEMORY.md and re-run
// consolidation so the artifact is regenerated
}
} Prevention
- Check that MEMORY.md is a regular file after any sync or merge operation.
- Exclude the memories root from tools that convert files to directories or links.
- Re-run consolidation after cleaning instead of hand-crafting the artifact.
When it happens
Trigger: After consolidation, root/MEMORY.md is a directory, a symlink to a directory, or another non-file entry (fifo, mount point).
Common situations: MEMORY.md replaced by a folder by sync/merge tools; symlinked from a dotfiles repo; partial merges leaving a directory where the file belongs.
Related errors
- path '{path}' is not a file
- timed out waiting for a client to subscribe to the thread af
- filename '{filename}' {reason}
- ad-hoc note must not be empty
- path '{path}' {reason}
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/074e0481bc3e7d1b.
Report an issue: GitHub.