# Antigravity runtime temp-dir cleanup starves the server's file I/O for minutes, and successful title generations report a timeout and retry · Issue \#23877 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/issues/23877)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: backlog

Priority: 0

## Description

[Discussion and activity](https://git.cafe/pingdotgg/t3code/issues/23877)

---

### What happened

On Windows, while I open and use my conversations, the desktop app shows **"`<host>` is reconnecting"** and **"T3 Code on `<host>` did not answer"**. The window stays open and the chats are visible, but the connection to the local backend stays degraded for many minutes. I first saw this on 0.1.1 and reproduced it on `0.1.2-nightly.20261022.3541`. Setting `UV_THREADPOOL_SIZE=16` (verified in the backend's environment) did not help.

The backend keeps listening on `127.0.0.1:3773`. `OPTIONS /` answers 204 in about 28 ms during the outage, but `GET /.well-known/t3/environment` times out. In one 5-minute sample: 4× 200, then 20 consecutive 3 s timeouts.

### Diagnosis

The outage lasts exactly as long as T3 is deleting an Antigravity runtime's PyInstaller temp directory. My **text generation model is Antigravity**, so every thread title runs the cycle below. My chat provider is Codex.

1. `ThreadTitleRegenerationService` calls `AntigravityTextGeneration.generateThreadTitle`. `AntigravityDriver.makeRuntime` creates a per-run `run-*` directory under `<stateDir>/antigravity-tmp/<hash>/`. The release step is `fileSystem.remove(directory, { recursive: true, force: true })` (`apps/server/src/provider/Drivers/AntigravityDriver.ts:223-240`).
2. `agy_acp_server.exe` unpacks its PyInstaller payload into `run-*/_MEI*`: at least 6,456 files, counted 17 s after the directory appeared (about 1 GB according to #11204).
3. The ACP prompt **succeeds in 3–7 s**. When the runtime scope closes, the recursive remove queues thousands of delete requests on the server's shared libuv pool. During the outage, **all 16 pool workers were blocked in `NtSetInformationFile(FileDispositionInformationEx)` on files under `run-*/_MEI*`**, read at 21:42 UTC during the second cleanup. A runtime snapshot during the first cleanup counted 2,494 pending `FSReqCallback`s.
4. Every other async fs call waits behind those deletes. `/.well-known/t3/environment` waits on `ServerSecretStore.get`, a plain `readFile`, so the descriptor times out, and the client shows reconnecting / did not answer. `fs.statSync` in the backend returned in 0 ms while an async `fs.stat` of the same directory did not finish in 2 s.
5. The runtime scope that holds the temp dir is closed **inside** `Effect.timeoutOption(ANTIGRAVITY_TIMEOUT_MS)` (180 s; inner `Effect.scoped` at `apps/server/src/textGeneration/AntigravityTextGeneration.ts:253`, timeout at `:270`). Cleanup time therefore counts against the timeout. A title that was generated successfully is reported as `"Antigravity text generation timed out."` and thrown away.
6. Initial titles retry twice (`ThreadTitleRegenerationService.ts:126-129`), so one title costs three launches and three cleanups. The outbox effect also survives backend restarts: it was on `attempt_count` 4 of 5 (`EffectWorker` `maxAttempts` 5). On restart, `removeAntigravityRuntimeTempDirs` sweeps the leftover tree at driver creation, which stalls startup the same way. It took 14.5 s on one launch and 49 s on the previous one, and `desktop.backendProcess.probeReadiness` took 16.8 s and 51.9 s.

On this machine the three cleanups took about 7.7, 9.3 and 4.2 minutes: about 21 minutes of a stalled server for one title. For comparison, `fs.rm` of 1,000 freshly written small files in a separate Node process took under 1 s. The cost comes from the size of the Antigravity tree. ESET Endpoint Security is installed and may add to it; that was not isolated.

Possible directions, for the maintainers to judge:
- Do the cleanup outside the timed region, and do not discard a completed generation because cleanup is slow.
- Delete the tree off the shared libuv pool, or with bounded concurrency, or detached from request-serving work.
- Avoid one full extraction per text-generation call.

### Steps to reproduce

1. Windows 11, T3 Code desktop `0.1.2-nightly.20261022.3541`, Antigravity provider installed and signed in.
2. Settings → text generation model: Antigravity (`gemini-3.8-flash-high` here).
3. Start a new thread with any provider and send the first message. This enqueues `thread-title.generate`.
4. Watch `%USERPROFILE%\.t3\userdata\antigravity-tmp\<hash>\run-*\_MEI*` fill with thousands of files, then get deleted after the prompt returns.
5. While it is being deleted, poll `GET http://127.0.0.1:3773/.well-known/t3/environment`: it times out and the app shows "reconnecting". `server.trace.ndjson` shows `session/prompt` Success, followed minutes later by `AntigravityTextGeneration.generateThreadTitle` Failure "timed out", then a retry.

How long each outage lasts depends on how fast the tree is deleted. Not tried on a second machine.

### Version

0.1.2-nightly.20261022.3541 (commit 044f072), desktop app with its local backend. Same symptom seen on 0.1.1; the mechanism was not verified there. The `t3 triage` CLI was also 0.1.2-nightly.20261022.3541.

### Environment

Windows 11 Pro 10.0.26200 x64, 22 logical CPUs, 31.5 GiB RAM. Desktop app (Nightly) with local backend (Electron, `ELECTRON_RUN_AS_NODE`). ESET Endpoint Security running. Chat provider Codex; text generation Antigravity `gemini-3.8-flash-high`.

### Evidence

```shell
# Backend libuv workers during the outage (UV_THREADPOOL_SIZE=16), 21:42 UTC, read with GetThreadContext.
# 16 of 16 workers, all the same call; 3 shown:
Wait/Executive  NtSetInformationFile  class=64 FileDispositionInformationEx flags=0x13  ~\.t3\userdata\antigravity-tmp\<hash>\run-QdmTr1\_MEI00007f702\google3\third_party\py\mcp\server\auth\errors.py
Wait/Executive  NtSetInformationFile  class=64 FileDispositionInformationEx flags=0x13  ~\.t3\userdata\antigravity-tmp\<hash>\run-QdmTr1\_MEI00007f702\google3\third_party\py\numpy\f2py\_backends\__init__.py
Wait/Executive  NtSetInformationFile  class=64 FileDispositionInformationEx flags=0x13  ~\.t3\userdata\antigravity-tmp\<hash>\run-QdmTr1\_MEI00007f702\google3\third_party\py\setuptools\_distutils\command\build_py.py
# Control: an idle plain Node process with 16 workers shows them as Wait/Unknown (NtWaitForAlertByThreadId).

# Backend active resources at 21:28:47 UTC (attempt 1 cleanup): FSReqCallback 2494; statSync(userdata) 0 ms; async stat(userdata) >2000 ms

# server.trace.ndjson (UTC)
21:25:01.572 -> 21:48:24.833  ThreadTitleRegenerationService.execute               1403260 ms Success
21:25:01.866 -> 21:33:23.105  AntigravityTextGeneration.generateThreadTitle         501239 ms Failure "Antigravity text generation timed out."
21:25:34.596 -> 21:25:37.862    session/prompt                                        3266 ms Success
21:33:25.109 -> 21:43:29.537  AntigravityTextGeneration.generateThreadTitle         604428 ms Failure "Antigravity text generation timed out."
21:34:04.655 -> 21:34:08.675    session/prompt                                        4020 ms Success
21:43:33.590 -> 21:48:24.804  AntigravityTextGeneration.generateThreadTitle         291214 ms Failure "Antigravity text generation timed out."
21:44:03.226 -> 21:44:09.843    session/prompt                                        6617 ms Success
# ServerSecretStore.get between 21:25 and 21:35: p50 177 ms, max 294323 ms
# environment.metadata.descriptor: repeated 10 s Interrupted from 21:26 to 21:32
# Startup: removeAntigravityRuntimeTempDirs 14549 ms (49124 ms on the previous launch)
# The descriptor returned 200 in 6-9 ms right after the title effect completed at 21:48:24.
```

### Related issues

#11204, #9650 and #12239 reported Antigravity `_MEI` folders being left behind and filling the disk. This issue is about the cost of deleting the per-run tree while the server is running, not about leftovers. #16932 had the same pool-starvation symptom from pipe reads; that was fixed by #17386, and the code is present in this build. #22586 is a different Windows stall (fff rescan on the event loop).

### Fix applied or workaround

Nothing was changed on the machine during triage. Workaround: switch the text generation model away from Antigravity. Raising `UV_THREADPOOL_SIZE` to 16 did not help.

### Filed by

Claude Code (claude-opus-5-5) via `t3 triage`
