Repository navigation
Installer adds hooks to both hooks.json and config.toml #570
Description
Summary
After installing codebase-memory-mcp, Codex starts with this warning:
loading hooks from both ~/.codex/hooks.json and ~/.codex/config.toml; prefer a single representation for this layer
It looks like the installer writes hook configuration into both hook representations at the same time.
What happened
The installation added a SessionStart hook to ~/.codex/config.toml:
[[hooks.SessionStart]]
matcher = "startup|resume|clear|compact"
[[hooks.SessionStart.hooks]]
type = "command"
command = 'echo "Code discovery: prefer codebase-memory-mcp (search_graph, trace_path, get_code_snippet, query_graph, search_code) over grep/file-read; run index_repository first if the project is not indexed."'
# <<< codebase-memory-mcp SessionStart <<<At the same time, ~/.codex/hooks.json also contains hook definitions, including a matching SessionStart hook with the same message:
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume|clear|compact",
"hooks": [
{
"type": "command",
"command": "echo \"Code discovery: prefer codebase-memory-mcp (search_graph, trace_path, get_code_snippet, query_graph, search_code) over grep/file-read; run index_repository first if the project is not indexed.\""
}
]
}
]
}
}This causes Codex to warn that hooks are being loaded from both hooks.json and config.toml.
Impact
For this specific hook, the impact is minor but visible:
- the startup/session hook message can appear more than once;
- Codex emits the warning about mixed hook representations;
- users may think their Codex or MCP setup is broken;
- if future hooks have side effects, duplicate hook sources could cause duplicate execution, slower startup, duplicated state writes, etc.
Expected behavior
The installer should prefer a single hook representation for the same layer, for example:
- write codebase-memory-mcp hooks only to
~/.codex/hooks.jsonif that file is already being used; or - write only to
~/.codex/config.toml; or - detect the existing representation and avoid adding the same hook to both places.
Suggested fix
During installation/setup, detect whether ~/.codex/hooks.json exists or whether Codex is already using TOML hooks, then install the SessionStart hook into only one location.
It may also be useful to add cleanup/migration logic that removes the duplicate codebase-memory-mcp SessionStart block from config.toml when the same hook already exists in hooks.json.
Activity
sahil-mangla commentedon Jun 23, 2026
@DeusData can i work on this?
test(repro): install/UX reproductions for #570, #409, #431
DeusData commentedon Jun 28, 2026
This issue now has a first-class, durable reproduction in the cumulative bug-reproduction suite landing in #667 — a test that pins the exact failing behaviour, so it's tracked and guarded against silent regression. Where #667 also lands the root-cause fix, that's called out in the PR; otherwise the reproduction makes the eventual fix straightforward and verifiable.
The reproduction goes live once #667 merges. (Posted from the release branch's QA pass.)
fix: 17 reproduce-first issue + new-bug fixes (per-case verified)
DeusData commentedon Sep 26, 2026
Thank you, @jiangjianzeng, for the precise report with both files quoted, and @sahil-mangla for offering to take it on!
The installer now picks one representation. If
~/.codex/hooks.jsonexists, the SessionStart reminder goes there and thecodebase-memory-mcp SessionStartblock is removed fromconfig.toml. Otherwise it stays inconfig.tomlonly. That removes Codex's "loading hooks from both" warning. This shipped in v0.9.0.Closing as fixed. Please reopen if a v0.11.0 install still writes both.