Malformed `[agents]` entry: config/read surfaces misleading "AbsolutePathBuf deserialized without a base path" while other loaders report the real error; config/batchWrite blocked
What version of the Codex App are you using (From "About Codex" dialog)?
ChatGPT desktop 26.803.41515 (bundled codex 0.147.0-alpha.6.5); also verified with standalone CLI 0.146.0
What subscription do you have?
Plus
What platform is your computer?
Darwin 25.5.0 arm64 arm (macOS 26.5.2)
What issue are you seeing?
Related context first: #19257 / #19261 fixed the legitimate case (a relative config_file in [agents.<role>] failing with "AbsolutePathBuf deserialized without a base path"). I verified that fix works in 0.147.0-alpha.6.5. This report is about a different trigger that produces the same misleading message, plus two behavior problems that follow from it.
Trigger: any unknown key under [agents] whose value is a 2-element array. This happened to me when the top-level notify array was accidentally placed inside the [agents] table (a TOML placement mistake — keys after a [table] header belong to that table):
[agents]
enabled = true
default_subagent_model = "gpt-5.6-terra"
notify = ["/path/to/notify-program", "turn-ended"] # parsed as agents.notify
Unknown [agents] keys are interpreted as agent-role definitions (AgentRoleToml, 3 elements), so ["/path/to/notify-program", "turn-ended"] is parsed as a role whose config_file is the string "turn-ended" — no actual path is involved. For this one file, three different behaviors are observed depending on which loader runs:
config/read(app-server) — the path the desktop UI uses for chat creation, composer submit, and conversation prewarm — returns:
``agents
invalid configuration: AbsolutePathBuf deserialized without a base path
in ``
This message is misleading (nothing is wrong with any path) and carries no file:line:column. Result: every chat creation fails ("Error creating local task", "[Composer] submit failed").
- Startup / reload / CLI loaders report a different, precise error for the same file:
````
config.toml:10:1: invalid length 2, expected struct AgentRoleToml with 3 elements
At startup the app degrades gracefully ("Invalid configuration; using defaults" + a configWarning notification with the exact file:line:column range), but config/read hard-fails — inconsistent degradation for the same file within the same process.
config/batchWriteis rejected (configValidationError) while the file is in this state, so the app cannot write any config change. In my incident, changing the model/reasoning effort in the UI failed with "Failed to update model and reasoning effort". Combined with (1), the app can neither be used nor self-repair; recovery requires a manual external edit of config.toml plus an app restart (on restart the app re-serializes config.toml and moves misplaced top-level keys back, which fixed it).
What steps can reproduce the bug?
Deterministic, isolated reproduction (no auth needed):
- Create an empty
CODEX_HOMEdir with thisconfig.toml(any unknown key with a 2-element array under[agents]works):
``toml``
[agents]
enabled = true
notify = ["/usr/bin/true", "turn-ended"]
- CLI (clear error):
``agents
$ CODEX_HOME=<dir> codex exec hi
Error loading config.toml: invalid length 2, expected struct AgentRoleToml with 3 elements
in ``
- app-server (misleading error — what the desktop UI shows):
````
$ CODEX_HOME=<dir> codex app-server # JSON-RPC over stdio
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"clientInfo":{"name":"Codex Desktop","version":"26.803.41515","title":"Codex Desktop"},"capabilities":{}}}
{"jsonrpc":"2.0","id":9,"method":"config/read","params":{}}
→ startup emits configWarning with config.toml:10:1: invalid length 2, expected struct AgentRoleToml with 3 elements (range line 10, cols 1–8), then config/read responds:
``jsonagents
{"error":{"code":-32603,"message":"invalid configuration: AbsolutePathBuf deserialized without a base path\nin \n"},"id":9}``
config/batchWriteagainst the same file fails withconfigValidationError(observed in the real incident; any write is rejected until the file is fixed externally).
Incident evidence (verbatim, from the desktop app's electron log under ~/Library/Logs/com.openai.codex/, times UTC):
07:08:08.057 error Request failed error={"code":-32603,"message":"invalid configuration: AbsolutePathBuf deserialized without a base path\nin `agents`\n"} failureReason=invalid_config method=config/read
07:08:08.058 error [Composer] submit failed cwd=~/dev/<project> errorMessage="invalid configuration: AbsolutePathBuf deserialized without a base path\nin `agents`\n"
07:09:00.080 error Request failed error={"code":-32600,"data":{"config_write_error_code":"configValidationError"},"message":"Invalid configuration: AbsolutePathBuf deserialized without a base path\nin `agents`\n"} method=config/batchWrite
07:09:00.081 error Failed to update model and reasoning effort
07:09:33.842 error Error creating local task errorMessage="invalid configuration: AbsolutePathBuf deserialized without a base path\nin `agents`\n"
07:09:51.702 error Request failed error={"code":-32603,"message":"failed to reload config: ~/.codex/config.toml:10:1: invalid length 2, expected struct AgentRoleToml with 3 elements"} method=app/installed
and from app-server tracing (~/.codex/logs_2.sqlite):
WARN codex_app_server::request_processors::account_processor:
failed to reload config, using startup config:
~/.codex/config.toml:10:1: invalid length 2, expected struct AgentRoleToml with 3 elements
What is the expected behavior?
- One consistent, actionable error for a malformed config across all loaders. The startup loader already produces the right one (with file:line:column); the
config/readpath should surface that instead of an internal serde-levelAbsolutePathBufmessage that points at a nonexistent path problem. - Consider having
config/readdegrade the way startup does (return config + warning) instead of hard-failing every chat creation. - Consider not holding all
config/batchWriteoperations hostage to one malformed section — otherwise the app cannot repair the file and the user must edit it externally and restart. (Understood that rewriting an unparsed file risks data loss; even a targeted error message telling the user which file/line to fix would help.) - Minor: unknown keys under
[agents]that collide with top-level config keys (notify) could be called out by name in the error.
Additional information
- The
AgentsToml/AgentRoleTomlschema and the clearinvalid length 2error exist identically in CLI 0.146.0 and 0.147.0-alpha.6.5. - Workaround for anyone hitting this: fix the misplaced key (top-level keys must appear before any
[section]header) or remove the offending entry; note also that explicit[agents.<role>]registration is optional —*.tomlunder$CODEX_HOME/agents/is auto-discovered (per #19257). - It could not be determined from logs which actor produced the misplaced
notifyline (an external tooling session and the app's own computer-use setup both wrote config.toml in the same window). The report is about the app's handling of the resulting file, independent of that question.
2 Comments
Adding a standalone reproduction/verification script. It is self-contained (temp
CODEX_HOMEonly, no auth needed) and asserts all three behaviors: the clear CLI error, the preciseconfigWarningnotification, and the misleadingconfig/readerror.Verified today on both codex CLI 0.146.0 and the bundled 0.147.0-alpha.6.5 — all three checks pass on both.
Sample output (codex CLI 0.146.0, macOS; identical on 0.147.0-alpha.6.5):
Note the two messages in [2a] vs [2b] are emitted for the same file within the same process: the startup path knows the exact location (line/column), while
config/read— the path the desktop UI depends on — returns the unrelatedAbsolutePathBufmessage without it.Re-verified on 0.148.0 (release binary, macOS arm64) with the standalone repro script above (isolated temp
CODEX_HOME, no auth). The loader divergence is unchanged:For an
[agents]table containing an unknown 2-element array entry (notify = ["/usr/bin/true", "turn-ended"]):Error loading config.toml: invalid length 2, expected struct AgentRoleToml with 3 elements inagents``configWarningnotification — carries the same real error withpath+range(line 1, columns 1–8).config/read(the response the desktop UI surfaces) — still the misleading downstream artifact:So on 0.148.0 the config/read path still reports the deserialization artifact instead of the real config error that (1) and (2) already produce, and
config/batchWriteremains blocked by the same invalid config, leaving the app unable to self-repair the file.