You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Windows Codex desktop app creates an empty .git folder, then spawns git process repetitively #29492
This list seems to match "Observed Commands" section reported in #29408.
What steps can reproduce the bug?
It's difficult to find out which kinds of prompt exactly reproduce the bug, but at some point Windows sandbox touches .agents, .codex, .git which eventually leads to multiple empty directories.
Sandbox log (timezone is UTC+9):
[2026-06-23 06:42:35.134 codex.exe] START: C:\Users\***\.codex\.sandbox-bin\codex.exe --codex-run-as-fs-helper
[2026-06-22T21:42:35.235850600+00:00] applied deny ACE to protect C:\Users\***\***\.agents
[2026-06-22T21:42:35.236659900+00:00] applied deny ACE to protect C:\Users\***\***\.codex
[2026-06-22T21:42:35.237416+00:00] applied deny ACE to protect C:\Users\***\***\.git
What is the expected behavior?
Codex should not create .agents, .codex, .git empty directories randomly.
Codex should not repeatedly spawn Git processes when .git folder is empty or malformed.
Additional information
I believe this issue is the first that enlightens the connection between an unexpected sandbox behavior and the Git process issue.
#28631 reported a similar bug but it's about VS Code extension on Linux/WSL.
This issue is about Windows desktop app, but the underlying cause may be likely identical.
I have the same issue, and it is problematic because the parent directory is where the real .git and .codex directories are located. As a result, the generated empty folder must be removed before new threads can correctly see my skills and git status again.
My current workaround is to delete those folders and reload the skills, but I have dozens of submodules under the parent directory, so this is quite annoying.
Same problem here. My workaround is a PowerShell script that finds empty .git folders and "git init"s them.
Before that, I had a loooot of Git processes spawning continuously; now, a few at the beginning and after nothing.
While waiting for a fix, I've taken the workaround script tip from @Apen and vibed a PowerShell script to identify and delete those empty folders. I now run it before any new thread and resumed 'normal' operation with codex.
The script searches from the root and enumerates all empty .git, .codex, .agents empty folders it finds and then deletes them; really saves me a lot of time.
While waiting for a fix, I've taken the workaround script tip from @Apen and vibed a PowerShell script to identify and delete those empty folders. I now run it before any new thread and resumed 'normal' operation with codex.
The script searches from the root and enumerates all empty .git, .codex, .agents empty folders it finds and then deletes them; really saves me a lot of time.
Where is this script?
Realistically where would I even have empty .git folders created "by mistake"?
I reccomend you vibe code with codex yourself, tailored for your specific case.
Here is my version, tailored for a multi module project:
<#.SYNOPSISFinds and permanently deletes empty .agents, .codex, and .git folders..DESCRIPTIONRun this script from the repo root. The repo root is treated as the folder thatcontains this script. The scan walks only through folders whose names do notstart with a dot, skips src and target folders, and it marks empty .agents,.codex, and .git child folders for deletion. The candidate folder names andexcluded traversal folder names are configurable through the $CandidateNames and$ExcludedTraversalNames lists near the top of the script..PARAMETERForceDeleteDeletes the marked empty folders without prompting for confirmation.#>
[CmdletBinding()]
param(
[Alias('Force')]
[switch] $ForceDelete
)
Set-StrictMode-Version Latest
$ErrorActionPreference='Stop'# Treat the folder containing this script as the repo root, no matter where the# caller's current PowerShell location happens to be.$RepoRoot= (Resolve-Path-LiteralPath $PSScriptRoot).ProviderPath
# Metadata folder names that should be deleted when they are empty.$CandidateNames=@('.agents','.codex','.git')
# Directory names that should not be traversed while searching.$ExcludedTraversalNames=@('src','target')
# Print a heartbeat every N scanned folders so long runs look alive.$ProgressInterval=250functionTest-EmptyDirectory {
param(
[Parameter(Mandatory=$true)]
[string] $Path
)
if (-not (Test-Path-LiteralPath $Path-PathType Container)) {
return$false
}
try {
# Reading one child is enough to prove the directory is not empty.$firstItem=Get-ChildItem-LiteralPath $Path-Force -ErrorAction Stop |Select-Object-First 1return$null-eq$firstItem
}
catch {
Write-Warning"Could not inspect folder: $Path"return$false
}
}
functionGet-ScannableDirectory {
param(
[Parameter(Mandatory=$true)]
[string] $Root
)
# Use an explicit stack so traversal can stream paths as they are found.$stack= [System.Collections.Generic.Stack[string]]::new()
$stack.Push($Root)
while ($stack.Count-gt0) {
$current=$stack.Pop()
$currentItem=Get-Item-LiteralPath $current-Force -ErrorAction Stop
if (($currentItem.Attributes-band [System.IO.FileAttributes]::ReparsePoint) -ne0) {
continue
}
# Emit the current folder before discovering its children.$current$children=Get-ChildItem-LiteralPath $current-Directory -Force -ErrorAction SilentlyContinue |Where-Object {
# Do not descend into dot folders, configured exclusions, or links.$_.Name-notlike'.*'-and$_.Name-notin$ExcludedTraversalNames-and
(($_.Attributes-band [System.IO.FileAttributes]::ReparsePoint) -eq0)
} |Sort-Object-Property FullName -Descending
foreach ($childin$children) {
$stack.Push($child.FullName)
}
}
}
# Track marked folders separately from already-seen paths so duplicate discovery# cannot print or delete the same path twice.$markedFolders= [System.Collections.Generic.List[string]]::new()
$seenFolders= [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
$scannedFolderCount=0Write-Host"Scanning under:"Write-Host"$RepoRoot"Write-Host"Empty metadata folders will be printed as they are found."Write-Host''# Stream the traversal so progress and found-folder output appears immediately.Get-ScannableDirectory-Root $RepoRoot|ForEach-Object {
$folder=$_$scannedFolderCount++if (($scannedFolderCount%$ProgressInterval) -eq0) {
Write-Host"Scanned $scannedFolderCount folders..."
}
foreach ($candidateNamein$CandidateNames) {
$candidatePath=Join-Path-Path $folder-ChildPath $candidateName# Mark only configured metadata folders that currently exist and are empty.if (Test-EmptyDirectory-Path $candidatePath) {
$resolvedPath= (Resolve-Path-LiteralPath $candidatePath).ProviderPath
if ($seenFolders.Add($resolvedPath)) {
Write-Host"Found: $resolvedPath"$markedFolders.Add($resolvedPath)
}
}
}
}
Write-Host''Write-Host"Scan complete. Scanned $scannedFolderCount folder(s)."# Keep the final confirmation list stable and deterministic.$markedFolders=@($markedFolders|Sort-Object-Unique)
if ($markedFolders.Count-eq0) {
Write-Host"No empty .agents, .codex, or .git folders found under:"Write-Host"$RepoRoot"exit0
}
Write-Host"The following empty folders are marked for permanent deletion:"foreach ($folderin$markedFolders) {
Write-Host"$folder"
}
# The default path requires a typed confirmation; -ForceDelete skips only this# prompt, not the final emptiness check before deletion.if ($ForceDelete) {
Write-Host''Write-Host'Force delete option supplied. Deleting without confirmation.'
}
else {
Write-Host''$confirmation=Read-Host'Type DELETE to permanently remove these folders'if ($confirmation-cne'DELETE') {
Write-Host'Cancelled. No folders were deleted.'exit0
}
}
$deletedCount=0$skippedCount=0foreach ($folderin$markedFolders) {
# Re-check just before deleting so changed folders are skipped safely.if (Test-EmptyDirectory-Path $folder) {
try {
Remove-Item-LiteralPath $folder-Force -ErrorAction Stop
Write-Host"Deleted: $folder"$deletedCount++
}
catch {
Write-Warning"Could not delete folder: $folder"$skippedCount++
}
}
else {
Write-Warning"Skipped because it is no longer empty or no longer exists: $folder"$skippedCount++
}
}
Write-Host''Write-Host"Done. Deleted $deletedCount folder(s). Skipped $skippedCount folder(s)."
Realistically where would I even have empty .git folders created "by mistake"?
In my case codex creates those 2-3 empty folders for every module I open in codex
Scan complete. Scanned 2635 folder(s).
The following empty folders are marked for permanent deletion:
R:\eda\cted\commons-desktop\commons-desktop-api\.agents
R:\eda\cted\commons-desktop\commons-desktop-api\.codex
R:\eda\cted\commons-desktop\commons-desktop-api\.git
R:\eda\cted\commons-desktop\commons-desktop-graph\.agents
R:\eda\cted\commons-desktop\commons-desktop-graph\.git
R:\eda\cted\game\game-ui\.agents
R:\eda\cted\game\game-ui\.codex
R:\eda\cted\game\game-ui\.git
R:\eda\cted\php-dashboard\.agents
R:\eda\cted\php-dashboard\.git
note that the main .git file would be at R:\eda\cted\.git, and so is the main .codex folder.
I ended up with creating empty .agents, .codex, .git files (not folders) with proper ACLs to mitigate this for now.
It's kind of unfortunate that this has not been noticed by OpenAI teams yet. I'm seeing several duplicate issues which means there are quite amount of users impacted by this specific bug in sense of the performance degradation. Hopefully this will be addressed soon.
It looks like this behavior also triggers Windows Defender to continuously scan the git-hammered folder. In my case, this doubles or triples the performance hit caused by the bug.
It's extremely noticeable. I can hear my fans spinning and a second after closing Codex, everything quiets down.
It starts Codex with a process-scoped GIT_DIR=NUL. On my machine, the stable trace changed from 247 new git.exe and 137 new taskkill.exe processes per 10 seconds to 0 and 0 over 15 seconds; WMI Provider Host fell from about 6.6% to 0.9%.
Usage: fully exit Codex from the Windows system tray, then run the script.
This is an unofficial workaround, not an upstream fix. It deliberately disables or limits Review, Changes, branch detection, commit, and other Git-backed Codex features. It does not patch Codex, modify repositories or Git configuration, write system environment variables, require elevation, terminate processes, or remove chat history. Launching Codex normally restores Git integration.
Activity
github-actions commentedon Jun 22, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
MinetaS commentedon Jun 23, 2026
#28631 reported a similar bug but it's about VS Code extension on Linux/WSL.
This issue is about Windows desktop app, but the underlying cause may be likely identical.
rasael commentedon Jun 25, 2026
I have the same issue, and it is problematic because the parent directory is where the real
.gitand.codexdirectories are located. As a result, the generated empty folder must be removed before new threads can correctly see my skills and git status again.My current workaround is to delete those folders and reload the skills, but I have dozens of submodules under the parent directory, so this is quite annoying.
GuilhermeCouto commentedon Jun 25, 2026
I have the same issue, my codex creates a .git folder inside of my project folder(1 level below the project folder with original .git) and bugs my IDE
Apen commentedon Jun 27, 2026
Same problem here. My workaround is a PowerShell script that finds empty .git folders and "git init"s them.
Before that, I had a loooot of Git processes spawning continuously; now, a few at the beginning and after nothing.
privacyguy123 commentedon Jun 29, 2026
Same bug is back in todays build for me - the previous fix was to delete an orphaned
.gitfolder in.codexbut there isn't one there anymore.rasael commentedon Jun 29, 2026
While waiting for a fix, I've taken the workaround script tip from @Apen and vibed a PowerShell script to identify and delete those empty folders. I now run it before any new thread and resumed 'normal' operation with codex.
The script searches from the root and enumerates all empty
.git,.codex,.agentsempty folders it finds and then deletes them; really saves me a lot of time.privacyguy123 commentedon Jun 29, 2026
Where is this script?
Realistically where would I even have empty
.gitfolders created "by mistake"?rasael commentedon Jun 29, 2026
I reccomend you vibe code with codex yourself, tailored for your specific case.
Here is my version, tailored for a multi module project:
In my case codex creates those 2-3 empty folders for every module I open in codex
note that the main
.gitfile would be atR:\eda\cted\.git, and so is the main.codexfolder.privacyguy123 commentedon Jun 30, 2026
You must admit this is an absolutely gross fix - why are orphaned
.gitfolders being created in the first place?MinetaS commentedon Jun 30, 2026
I ended up with creating empty
.agents,.codex,.gitfiles (not folders) with proper ACLs to mitigate this for now.It's kind of unfortunate that this has not been noticed by OpenAI teams yet. I'm seeing several duplicate issues which means there are quite amount of users impacted by this specific bug in sense of the performance degradation. Hopefully this will be addressed soon.
rolandorojas commentedon Jul 5, 2026
It looks like this behavior also triggers Windows Defender to continuously scan the git-hammered folder. In my case, this doubles or triples the performance hit caused by the bug.
It's extremely noticeable. I can hear my fans spinning and a second after closing Codex, everything quiets down.
amerina commentedon Jul 9, 2026
this problem fuck me every day😭,can god resolve this,because company us tfs still
suiyuebaobao commentedon Jul 22, 2026
The empty
.gitdiscovery loop and repeated Git spawning here are the same class of Git-backed refresh workload I reproduced.I published a single-file Windows launcher for the original Microsoft Store/MSIX Codex app:
It starts Codex with a process-scoped
GIT_DIR=NUL. On my machine, the stable trace changed from 247 newgit.exeand 137 newtaskkill.exeprocesses per 10 seconds to 0 and 0 over 15 seconds; WMI Provider Host fell from about 6.6% to 0.9%.Usage: fully exit Codex from the Windows system tray, then run the script.
This is an unofficial workaround, not an upstream fix. It deliberately disables or limits Review, Changes, branch detection, commit, and other Git-backed Codex features. It does not patch Codex, modify repositories or Git configuration, write system environment variables, require elevation, terminate processes, or remove chat history. Launching Codex normally restores Git integration.