anomalyco / anomalyco/opencode
Native crash (SIGTRAP) in fff-scan thread during watcher resubscribe after scan — FileItem::write_absolute_path overflows fixed 1024-byte buffer (macOS arm64)
@kitlangton is already working on this.
Since Aug 19, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
opencode crashes with a native Rust panic in the bundled fff file-indexer during a scan, killing the whole process with no error in opencode.log.
- opencode: 1.18.18 (latest at time of filing)
- Platform: macOS 26.5.2, Apple Silicon (arm64)
- Crash reports:
~/Library/Logs/DiagnosticReports/opencode-2026-08-18-210957.ipsandopencode-2026-08-18-222412.ips— two crashes ~75 min apart, byte-identical faulting stack.
Crash signature
EXC_BREAKPOINT / SIGTRAP
faultingThread: 33, thread name: "fff-scan"
fff_search::types::FileItem::write_absolute_path::h6be4aaca40dafd85
fff_search::scan::rescubscribe_watcher_post_scan::hd9b19e5fc8d2229e
fff_search::scan::ScanJob::run::hb82750f8c22d9326
std::sys::backtrace::__rust_begin_short_backtrace
core::ops::function::FnOnce::call_once{{vtable.shim}}
std::sys::thread::Thread::new::thread_start
What was happening
Both crashes occurred during long agentic sessions in a git repo with multiple worktrees (jot-brain, jot-brain-wt119, jot-brain-wtsec). The app log shows the session running a rescan loop and stopping abruptly mid-step with no error line:
...loop session.id=ses_... step=243
[trace/breakpoint trap] ← process dies here, nothing logged
Root cause hypothesis (from fff source)
The panic is in FileItem::write_absolute_path (fff-core/src/types.rs), which writes base_path + '/' + relative_path into a fixed-size stack buffer:
#[cfg(not(target_os = "windows"))]
pub const PATH_BUF_SIZE: usize = libc::PATH_MAX as usize; // 1024 on macOS
pub(crate) fn write_absolute_path<'a>(&self, arena, base_path, buf: &'a mut [u8; PATH_BUF_SIZE]) {
let base_len = base.len();
buf[..base_len].copy_from_slice(base); // panics if base_len > 1024
...
buf[base_len] = std::path::MAIN_SEPARATOR as u8; // panics if base_len == 1024
...
}
There is no bounds check. During ScanJob::run → rescubscribe_watcher_post_scan (fff-core/src/scan.rs), the watcher is re-subscribed to every indexed directory; any directory path ≥ PATH_BUF_SIZE (1024 on macOS) causes a slice index out of range Rust panic.
Rust panics in the native lib abort the process via an int3 trap → recorded by macOS as EXC_BREAKPOINT/SIGTRAP, and bypass the opencode JS logger, so the app log just ends mid-loop with no error. The two identical .ips files confirm a deterministic trigger rather than two unrelated incidents.
Related
- #42557 — fff watcher / libgit2 busy-loop (same fff code area)
- #32511, #35791, #37740 — fff over-indexing / watch explosion
- #31682, #31747, #31701, #31850 — earlier (closed) fff scan crashes in 1.17.x
Ask
- Bounds-check the path write in
write_absolute_path(fall back to heapPathBufwhenPATH_BUF_SIZEis exceeded). - Consider raising
PATH_BUF_SIZE/ not truncating silently.
Crash reports available on request.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.