Repository navigation
Description
Description
Problem
Every invocation of opencode — including headless modes like opencode run --format json and opencode serve — extracts an identical copy of libopentui.so (~4.3 MB) into /tmp with a randomized filename. The file is never cleaned up on process exit.
In environments where opencode is called frequently (e.g., as a coding agent backend via opencode run --format json, or with oh-my-opencode background agents), this causes /tmp to grow by gigabytes per hour and eventually exhausts root disk space.
Observed behavior
$ ls -la /tmp/.fcbc*.so | head -3
-rw-r--r-- 1 user users 4467856 Apr 7 18:59 /tmp/.fcbcce070aa9c41f-00000000.so
-rw-r--r-- 1 user users 4467856 Apr 7 18:59 /tmp/.fcbcce071be8fd7f-00000000.so
-rw-r--r-- 1 user users 4467856 Apr 7 18:59 /tmp/.fcbcce071bebfe2d-00000000.so
$ ls /tmp/.fcbc*.so | wc -l
5881
$ md5sum /tmp/.fcbc*.so | awk '{print $1}' | sort -u
b937f51f51f919d80cdbb94e5486f51f # all 5881 files are identical
5881 identical copies = ~25 GB consumed in a single day.
strace confirms: each invocation creates a new file, writes 4,467,856 bytes of ELF data, mmaps it, and never calls unlink on exit:
openat(13, ".fcbcff3fbbabc6fd-00000000.so", O_WRONLY|O_CREAT|O_CLOEXEC, 0644) = 14
write(14, "\177ELF\2\1\1\0...", 4467856) = 4467856
close(14)
openat(AT_FDCWD, "/tmp/.fcbcff3fbbabc6fd-00000000.so", O_RDONLY|O_CLOEXEC) = 14
mmap(NULL, 5034944, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 14, 0) = 0x...
# process exits — zero unlink calls
Two independent root causes
1. Embedded Bun runtime is v1.2.8, which has a known temp file leak
OpenCode (tested across versions 1.2.27 through 1.3.17) embeds Bun v1.2.8 as its standalone runtime. This version has a known bug where resolveEmbeddedFile() in ModuleLoader.zig creates a new randomly-named temp file on every call and never cleans it up.
This was fixed in Bun v1.2.13 (oven-sh/bun#19550) — the fix adds automatic deletion of temp files on process exit.
Upgrading the embedded Bun to >= v1.2.13 would resolve the leak.
Verification:
# Every opencode version tested embeds the same broken Bun:
$ strings opencode-linux-x64@1.2.27/bin/opencode | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -1
1.2.8
$ strings opencode-linux-x64@1.3.17/bin/opencode | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -1
1.2.82. opencode run --format json loads opentui unnecessarily
Even in headless/non-TUI mode (--format json, serve), opencode imports the opentui module, which eagerly calls dlopen() on libopentui.so at the top level (zig.ts:3881-3884):
// Eager loading at module level — runs regardless of whether TUI is needed
try {
opentuiLib = new FFIRenderLib(opentuiLibPath)
} catch (error) {}This means every opencode run --format json call triggers the full native lib extraction + dlopen chain, even though no terminal rendering occurs.
Conditionally importing opentui only in TUI mode would eliminate the extraction entirely for headless use cases.
Impact
- Production servers running
opencode serveaccumulate temp files on every restart - Platforms using
opencode run --format jsonas a coding agent backend (one extraction per user message) see steady disk growth - Users have reported 60+ GB consumed overnight (#6523)
- At least one user has abandoned opencode due to this issue
Suggested fixes
-
Upgrade embedded Bun to >= v1.2.13 — This is the most impactful fix. Bun v1.2.13 automatically deletes extracted temp files on process exit (oven-sh/bun#19550).
-
Skip opentui import in headless modes — When running with
--format jsonor asserve, conditionally skip the opentui module import to avoid the native lib extraction entirely. This would also improve startup time for headless invocations.
Related issues
| Repo | Issue | Title |
|---|---|---|
| oven-sh/bun | #19550 | Single-file executable doesn't clean up temporary .node files in /tmp (fixed in v1.2.13) |
| anomalyco/opentui | #649 | Ignores TMPDIR and fails when /tmp is mounted as noexec |
| anomalyco/opentui | #355 | Remove top-level await to enable bytecode compilation |
| anomalyco/opencode | #6523 | opencode creates identical temp files everytime it runs |
| anomalyco/opencode | #13479 | /tmp fills up after three days of usage |
| anomalyco/opencode | #16996 | Runaway /tmp .so artifacts can exhaust disk |
| anomalyco/opencode | #20043 | Headless opencode serve still extracts libopentui.so |
Environment
- OpenCode: 1.3.17 (also reproduced on 1.2.27, 1.3.0, 1.3.13)
- Embedded Bun: v1.2.8
- OS: Linux 5.10 x86_64
- opentui: 0.1.87 (bundled)
Plugins
No response
OpenCode version
No response
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response
Activity
github-actions commentedon Apr 8, 2026
This issue might be a duplicate of existing issues. Please check:
opencode servestill extracts libopentui.so into /tmp on every start, causing temp artifact buildupIf your issue is distinct from all of the above (e.g., you have new reproduction details or a different root cause), feel free to clarify. Otherwise, consider adding your findings as a comment to one of the existing issues.
axwfae commentedon Apr 9, 2026
Even if you upgrade the bundle to (1.3.11+af24e281e), it will still generate useless files and will not delete them.
jerome-benoit commentedon May 5, 2026
The embedded Bun version has since been upgraded to v1.3.11 (well past the v1.2.13 fix in oven-sh/bun#19550), so root cause #1 should no longer apply to current releases.
Root cause #2 (opentui loaded eagerly in headless mode) may still be relevant — opentui is now at v0.2.2 but it's unclear if the conditional import was addressed.
This issue was also reported downstream in njbrake/agent-of-empires#904 where opencode runs as a coding agent backend inside tmux sessions, accumulating identical
/tmp/.f9ef7ff*-00000000.sofiles over time.mikew commentedon May 15, 2026
Actually, the files are almost twice as large now:
github-actions commentedon Jul 15, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.
thdxr commentedon Aug 19, 2026
Update: the unbounded native-library temp-file growth described here is fixed in OpenCode V2.
As of V2 build
0.0.0-dev-17643, the compiled CLI uses Bun 1.4.0-canary.1 (681a49bee). That runtime includes oven-sh/bun#29587, which replaces the unique temporary.so/.dylib/.nodeextraction on every load with a deterministic, content-hashed path reused across calls, Workers, processes, and restarts. The V2 build provenance is workflow run 32216069554.This bounds extraction to one reusable file per embedded native module and user instead of allowing unbounded disk growth. It does not mean the temp directory will contain zero native files, and upgrading does not remove files leaked by older builds; those stale randomly named files can be cleaned up after all older OpenCode processes have stopped.
fix: probe OpenCode once per daemon start and again only when its bin…