Repository navigation
inbox: an unreadable inbox is one MAILBOX_ERROR line and exit 5; the loops report it once and drop the mailbox (#98) - #157
Merged
Merged
Conversation
…tack trace; the loops report it once and drop the mailbox (#98)
deanbot
marked this pull request as ready for review
November 2, 2026 03:36
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.
What changed and why
inbox.mjs --dir <inbox>reads a loop's inbox every cycle. When the folder couldn't be read (ENOTDIR: the path is a file or lies under one; EACCES: no read permission), it threw, printed a stack trace and exited 1, on every cycle. No loop said what that meant, so a session could retry forever or read the failure as "no messages".--checkrefuses such paths at the start; this covers a folder that goes bad after the check.scripts/inbox.mjs. Before any read or wait,--waitincluded, it tries the folder once. If the folder exists but can't be read, it prints one line,MAILBOX_ERROR: <inbox>: <code>, and exits 5, with no stack trace. Exit 1 is a usage error, and 3 and 4 are the waiter's (WATCHER_RUNNING, a takeover). An inbox that doesn't exist is stillNONE.MAILBOX_ERROR, report it once:⚠ Mailbox off: <the line>; running without it.in the status line and the same line to the outbox. Then run without the mailbox for the rest of the session: no step 0, and no--inboxon any waiter. The read is never retried each cycle.Done, and the checks that show it
All in
scripts/test/run.mjs, inbox section, tests namedinbox (#98): ….One line naming the inbox and the error code, a distinct non-zero exit, no stack trace:
MAILBOX_ERROR: <inbox>: ENOTDIRand exit 5;--wait, the same line and exit 5 at once, with no wait;EACCESand exit 5. Root can read any folder, so under root this case checks only the exit.Each of these checks there are no
at …frames and noError:.The skills say what to do on the line: a text test checks that every Claude Code loop reports it once (status line and outbox) and then runs without the mailbox, never retrying. Generic and Kiro read no inbox: their start check always prints
NO_MAILBOX, so the line can't reach them.The spec names the line and the exit code: SPEC, "A folder that goes bad after the start".
Contract tests: the four script cases above. Also, a missing inbox is still
NONEwith exit 0.Mutation-checked: removing the new folder check fails all four
MAILBOX_ERRORcases.Calls a reviewer might push back on
--waitis a failed pass, and the waiter logs it and retries as for any other. The loops run--dirone-shot each cycle, so the next cycle gets the line.Restart note
All three Claude Code roles (executor, reviewer, QA) need a fresh session to pick up the text. Generic and Kiro: none. Setup doesn't need re-running.
Closes #98