Codex app-server spins on repeated git rev-parse when workspace has invalid empty .git directory
Summary
If a Codex workspace contains a .git directory that exists but is not a valid Git repository, the local Codex app-server appears to enter a tight Git root detection loop. It repeatedly launches:
git -c core.hooksPath=/dev/null -c core.fsmonitor= rev-parse --show-toplevel
On my machine this kept the app-server around one CPU core continuously until the invalid .git directory was fixed.
Environment
- Codex CLI:
codex-cli 0.142.4 - Build path indicated:
0.142.4-x86_64-unknown-linux-musl - OS: Linux x86_64, Ubuntu kernel
7.0.0-27-generic - Surface: Codex desktop/local app-server, process shown as
codex app-server --listen unix://
Likely repro
- Create or open a workspace directory that contains an empty/broken
.gitdirectory:
``bash``
mkdir -p /tmp/codex-broken-git/.git
cd /tmp/codex-broken-git
git rev-parse --show-toplevel
- Confirm Git exits with:
``text``
fatal: not a git repository (or any of the parent directories): .git
- Open that workspace in Codex desktop/app-server.
- Watch the app-server process CPU and child process creation.
Observed behavior
- The app-server stayed hot for several minutes, typically around
90%to160%CPU in interval readings. - A short
stracesample showed1494execveattempts involvinggit ... rev-parse --show-toplevelin roughly 3 seconds. - The app-server repeatedly searched PATH for
git, then launched/usr/bin/git. - The loop persisted after the Codex log database was replaced with a fresh small database, so this did not appear to be caused by log DB corruption.
- Running
git initin the affected workspace, turning the empty.gitdirectory into valid Git metadata, immediately dropped app-server CPU from roughly one core to low single digits.
Expected behavior
Codex should treat an invalid .git directory as either:
- not a Git repository, or
- a recoverable workspace metadata error that is logged/surfaced once,
and then cache/back off the failed root detection. It should not continuously spawn git rev-parse in a tight loop.
Workaround
Either remove the broken .git directory or initialize/fix it:
rm -rf .git
# or
git init
After git init, the app-server CPU returned to normal.
4 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Current-main source trace for the likely split here:
codex-rs/git-utils/src/info.rs::get_git_repo_rootis a lightweight marker walk. It treats any ancestor.gitfile or directory as a repo root marker without validating that Git can actually open it.ThreadMetadataSync::for_createincodex-rs/thread-store/src/thread_metadata_sync.rsthen uses that marker result as the gate forcollect_git_info(cwd).await.collect_git_infoimmediately shells out to Git (rev-parse --git-dir, then other metadata commands if successful).codex-rs/git-utils/src/operations.rs::resolve_repository_rootshells out togit rev-parse --show-toplevel, and the sharedrun_githelper injects-c core.hooksPath=/dev/null, matching the command shape reported in this issue.So an empty/broken
.gitdirectory can be classified as "git workspace" by Codex's marker-only path while Git itself rejects it as not a repository. If that classification is recomputed by a workspace/status/watch loop without negative caching, the app-server can keep spawning short-lived failing Git commands.Suggested fix boundary:
.gitor the cwd changes.Regression shape:
.gitdirectory.rev-parse.Same issue on a Linux SSH remote used from Codex Desktop on Windows. The workspace contained an empty/invalid .git-directory. After deleting the .git-directory the high CPU issue appears to be resolved.
I prepared a fix branch for this, but GitHub says this repository only allows collaborators to open pull requests.
Branch: https://github.com/kalayciburak/codex/tree/fix/validated-git-metadata-root
Compare: https://github.com/openai/codex/compare/main...kalayciburak:fix/validated-git-metadata-root
The change adds metadata-specific Git root validation so empty
.gitdirectories and brokengitdir:pointer files are ignored before background Git metadata probes. It covers turn metadata, memory workspace metadata, rollout session metadata, thread metadata sync, andgit_diff_to_remote.Validated with:
cargo test -p codex-git-utils git_repo_root_for_metadata --libcargo check -p codex-git-utils -p codex-core -p codex-rollout -p codex-thread-storecargo fmt --checkgit diff --check