What happens
On a headless Linux host running t3 serve with the OpenCode provider enabled, /tmp steadily fills with hidden shared objects:
-rw-r--r-- 1 user1 user1 8202200 Jul 10 00:50 /tmp/.3af8e77eefdd7ffb-00000000.so
-rw-r--r-- 1 user1 user1 8202200 Jul 10 00:55 /tmp/.3af8e7fedebfbffe-00000000.so
-rw-r--r-- 1 user1 user1 8202200 Jul 10 01:00 /tmp/.3af8e7fdff9f3ffe-00000000.so
-rw-r--r-- 1 user1 user1 8202200 Jul 10 01:05 /tmp/.3af8e87cee597ffb-00000000.so
One 8.2 MB file appears every ~305 seconds, indefinitely: roughly 2.4 GB/day. The host had accumulated 8.9 GB in /tmp over six days before this was noticed.
Root cause
Each file is an unstripped x86-64 ELF with debug_info whose symbols are miniaudio (ma_node_graph_init, ma_node_init, ...): the output of Bun's bun:ffi cc(), which the OpenCode binary uses for its audio notification support. Watching /tmp and catching a creation in the act shows the producer is a one-second-old opencode serve spawned by t3:
NEW: /tmp/.3af8e87fdeddbfff-00000000.so at 01:10:51
USER PID ACCESS COMMAND
/tmp/.3af8e87fdeddbfff-00000000.so:
user1 2482594 ....m opencode
2482594 user1+ 1 opencode serve --hostname=127.0.0.1 --port=36701
The five-minute cadence matches the provider snapshot refresh (SNAPSHOT_REFRESH_INTERVAL = Duration.minutes(5) in apps/server/src/provider/Drivers/OpenCodeDriver.ts). Each refresh spawns a fresh short-lived opencode serve on an ephemeral port to probe provider status, OpenCode's Bun runtime compiles miniaudio to a temp .so in /tmp during startup, t3 tears the probe server down, and nothing deletes the file. The compile-to-tmp behavior itself is upstream OpenCode/Bun (unstripped debug object, no caching, no unlink after load), but the spawn-per-probe refresh loop is what turns a one-off 8 MB temp file into unbounded disk growth on every host that leaves t3 serve running.
Environment
- t3 0.0.27 (
npx t3 serve, headless), Node v24.16.0, Ubuntu x86-64
- OpenCode provider enabled
Suggested fixes
- Reuse a persistent OpenCode server (or cache the probe result) instead of spawning a fresh
opencode serve for every snapshot refresh.
- Run provider probe processes with
TMPDIR pointed at a per-probe directory that t3 removes on teardown, so any temp litter from provider binaries is contained regardless of which provider produces it.
- Upstream in OpenCode/Bun: compile the FFI object stripped, cache it by source hash, or unlink it after
dlopen; a way to disable audio in server mode would remove the trigger entirely.
Related but distinct: #3646 tracks git tmp_pack litter from checkpoint capture, and #2657 hardens teardown of leaked probe processes; this is the temp-file counterpart of the same probe loop.
Workaround until fixed: a timer that prunes the litter, e.g. find /tmp -maxdepth 1 -name ".*.so" -mmin +15 -delete every 10 minutes.
What happens
On a headless Linux host running
t3 servewith the OpenCode provider enabled,/tmpsteadily fills with hidden shared objects:One 8.2 MB file appears every ~305 seconds, indefinitely: roughly 2.4 GB/day. The host had accumulated 8.9 GB in
/tmpover six days before this was noticed.Root cause
Each file is an unstripped x86-64 ELF with
debug_infowhose symbols are miniaudio (ma_node_graph_init,ma_node_init, ...): the output of Bun'sbun:fficc(), which the OpenCode binary uses for its audio notification support. Watching/tmpand catching a creation in the act shows the producer is a one-second-oldopencode servespawned by t3:The five-minute cadence matches the provider snapshot refresh (
SNAPSHOT_REFRESH_INTERVAL = Duration.minutes(5)inapps/server/src/provider/Drivers/OpenCodeDriver.ts). Each refresh spawns a fresh short-livedopencode serveon an ephemeral port to probe provider status, OpenCode's Bun runtime compiles miniaudio to a temp.soin/tmpduring startup, t3 tears the probe server down, and nothing deletes the file. The compile-to-tmp behavior itself is upstream OpenCode/Bun (unstripped debug object, no caching, no unlink after load), but the spawn-per-probe refresh loop is what turns a one-off 8 MB temp file into unbounded disk growth on every host that leavest3 serverunning.Environment
npx t3 serve, headless), Node v24.16.0, Ubuntu x86-64Suggested fixes
opencode servefor every snapshot refresh.TMPDIRpointed at a per-probe directory that t3 removes on teardown, so any temp litter from provider binaries is contained regardless of which provider produces it.dlopen; a way to disable audio in server mode would remove the trigger entirely.Related but distinct: #3646 tracks git
tmp_packlitter from checkpoint capture, and #2657 hardens teardown of leaked probe processes; this is the temp-file counterpart of the same probe loop.Workaround until fixed: a timer that prunes the litter, e.g.
find /tmp -maxdepth 1 -name ".*.so" -mmin +15 -deleteevery 10 minutes.