watcher: inotify arm panics on every Linux start (raw syscall checked with the libc errno accessor) - #698
Merged
justrach merged 1 commit intoAug 22, 2026
Conversation
`armInotify` and `addInotifyWatch` classify raw `std.os.linux.*` returns with
`std.posix.errno`. That is the libc accessor — `if (rc == -1) ... else .SUCCESS`
— and a raw syscall returns `-errno` packed into a usize, which never equals
-1. So the guard reported `.SUCCESS` for every failure and the negative rc fell
through to `@intCast(...)`: a panic in Debug/ReleaseSafe, a truncated garbage
watch descriptor in ReleaseFast.
It fires on startup for everyone on Linux. `armInotify` watches
`/tmp/codedb-notify` — the optional muonry interop file that codedb itself
never creates — so a machine without muonry takes `-ENOENT` on every arm. The
kqueue path already tolerated its absence (`else |_| {}`); only inotify did not.
Reproduced as a hard crash in `test_index` "issue-690".
Classify with the -errno range instead. `rawLinuxSyscallFailed` mirrors
std.os.linux.errno without referencing the linux-only namespace, so the
boundary behaviour is unit-testable on every target.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TqTyTJVJ4cd1MzFF54Hrbh
justrach
marked this pull request as ready for review
August 22, 2026 16:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
FileChangeWatchguards two rawstd.os.linux.*syscalls with the wrong errno accessor:codedb links libc, so
std.posix.errnoresolves tostd.c.errno, which reports failure only forrc == -1. Ausizenever equals-1, so the guard always returned.SUCCESSand the negative rc fell straight through to@intCast.Verified against the pinned toolchain (0.17.0-dev.813+2153f8143):
Why it fires for everyone on Linux
armInotifywatches/tmp/codedb-notify— the optional muonry interop file, which codedb itself never creates. On any machine without muonry that watch returns-ENOENTon every arm, so:integer does not fit in destination type) in the watcher thread.@intCastis unchecked, so the value truncates to a garbage watch descriptor instead. That is why shipped releases never surfaced it:/tmp/codedb-notifyalso fails silently, and a failing directory watch (EACCES, watch-limit ENOSPC) inserts a boguswd -> relmapping that can misattribute later events.The kqueue path already tolerated the file's absence (
else |_| {}); only inotify did not.Failing test
Reproduces today on
release/0.2.5842as a crash in the existing test:Fix
Classify raw returns by the
-errnorange instead.rawLinuxSyscallFailedmirrorsstd.os.linux.errnowithout referencing the linux-only namespace, so the boundary behaviour stays unit-testable on every target. Applied at both call sites —inotify_init1had the identical bug.I scanned
src/for other rawstd.os.linux.*call sites; these two are the only ones.Verification
watcher: raw linux syscall failures are detected by the -errno rangepins success values,-ENOENT, and the-1/-4095/-4096boundaries.issue-690crashes and the new test fails; with the fix, both pass.zig build test25/25 steps, 807/811 passed, 4 skipped, 0 failed, 0 crashed (previously 1 crash)./tmp/codedb-notifyabsent — arms and runs clean.