Repository navigation
Description
Client or integration
OpenCodex proxy state persistence (observed while using Codex App)
Area
Proxy and routing
Summary
On OpenCodex 2.7.40 on Windows, stale atomic-write temporary files for responses-state.json accumulated indefinitely under the OpenCodex config directory:
- pattern:
responses-state.json.ocx.<pid>.<sequence>.tmp - count: 263 files
- total size: 5.88 GB
- creation period: July 20–25, 2026
- all PIDs encoded in the stale filenames were no longer running
I expected interrupted/failed response-state writes to be cleaned up, either during the failed write or on a later proxy startup. Instead, crash/forced-termination remnants survived multiple restarts and consumed several gigabytes.
This report is about unbounded stale state files and disk/privacy hygiene. I am not claiming that their mere presence was the primary cause of dashboard latency; a separate issue reports the independently measured usage.jsonl performance problem.
Reproduction
The exact interruption timing has not yet been reduced to a deterministic single command. The production observation followed several proxy crashes or forced terminations while responses-state.json was large and actively persisted.
A likely reproduction path is:
- Use Responses/Codex conversations long enough for
responses-state.jsonto grow substantially. - Terminate the proxy while the debounced response-state snapshot is being persisted.
- Restart and repeat.
- Inspect the OpenCodex config directory for stale files:
$home = Join-Path $HOME '.opencodex'
$tmp = Get-ChildItem -LiteralPath $home -File -Filter 'responses-state.json.ocx.*.tmp'
$tmp | Measure-Object Length -Sum
$tmp | Select-Object Name, Length, LastWriteTimeObserved filename PIDs were:
3200, 6400, 6664, 10168, 15772, 17400, 32660
None were alive when checked. The newly restarted proxy PID did not occur in any stale filename.
Cleanup observation, without asserting a root cause: PowerShell Remove-Item, Copy-Item, and Rename-Item returned access denied for sampled stale files, while [System.IO.File]::Delete() succeeded. File owner/attributes alone did not explain the difference, so this should be treated only as an observed Windows cleanup behavior.
Implementation notes
In 2.7.40:
src/responses/state.ts:136-164serializes the response-state snapshot and callsatomicWriteFile(...)from a best-efforttry/catch.src/config.ts:80-125creates${path}.ocx.${process.pid}.${sequence}.tmpand attempts truncate/unlink cleanup on ordinary exceptions.- An abrupt process termination can bypass that cleanup path.
persistNow()swallows disk failures because the snapshot is a cache, so a cleanup failure may leave no durable diagnostic.- I did not find a startup sweep/doctor check for stale
responses-state.json.ocx.*.tmpfiles.
The temporary files can contain persisted conversation response state, so accumulation is also undesirable from a data-retention perspective even when file permissions are hardened.
Expected behavior
Please consider:
- Cleaning stale atomic-write temp files on startup using a strict basename pattern, minimum age/grace period, and live-PID protection.
- Keeping normal exception cleanup, but adding recovery for abrupt termination leftovers.
- Reporting stale temp count/bytes in
ocx doctoror the Storage page. - Ensuring cleanup never touches the active write or unrelated
.tmpfiles. - Adding a regression test that leaves a fixture temp file from a dead PID and verifies bounded startup recovery.
Version
@bitkyc08/opencodex 2.7.40
Operating system
Windows NT build 10.0.26200.8875 (x64)
Provider and model
Not provider-specific.
Logs or error output
Before cleanup:
stale files: 263
total size: 5.88 GB
active-PID conflicts: 0
After bounded manual cleanup:
stale files: 0
disk space recovered: approximately 5.88 GBRedacted configuration
Not configuration-specific.
Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Activity
github-actions commentedon Jul 26, 2026
Automated translation bookkeeping — detected language: English.
Ingwannu commentedon Jul 26, 2026
Confirmed against current
dev(911373db). Normal atomic-write exceptions attempt cleanup, but an abrupt process termination can leaveresponses-state.json.ocx.<pid>.<seq>.tmpfiles and there is no later bounded recovery sweep. With a 24 MiB response-state snapshot cap, the reported multi-gigabyte accumulation is consistent with the current design.I will add a strict response-state-only recovery pass with:
Focused regressions will cover dead/current PID files, young files, unrelated names, and cleanup failure behavior. I will link the
devPR and verification here before closing.Ingwannu commentedon Jul 26, 2026
Fixed and merged into
devvia PR #502.The recovery pass now:
responses-state.json.ocx.<pid>.<seq>.tmp;The initial plan mentioned truncate-before-unlink, but review identified a path-replacement/symlink TOCTOU risk. The landed implementation deliberately uses unlink-only cleanup, which removes the stale directory entry without ever following a replacement path to scrub an arbitrary target.
Verification: 38 focused response-state tests passed, full TypeScript typecheck passed, all PR CI checks passed on Ubuntu, macOS, and Windows, and the final review queue had no unresolved threads.