Skip to content

Keep the server running when a job's state write fails with ENOSPC - #85

Merged
JOsacky merged 1 commit into
mainfrom
fix/daemon-enospc-crash
Nov 11, 2026
Merged

JOsacky merged 1 commit into
mainfrom
fix/daemon-enospc-crash

Conversation

@JOsacky

@JOsacky JOsacky commented Nov 11, 2026

Copy link
Copy Markdown
Member

Why

On 2026-11-11 the operator Mac ran out of disk. Between 03:49 and 06:00Z the main skillhook daemon (0.15.2) restarted 18 times, and each restart marked the jobs it was running as interrupted: 29 jobs in total. The service log has 8 daemon uncaught exception ... ENOSPC traces. They come from:

  • JobStore.update → writeJsonFile, called from the child.once("spawn") handler (queue.js:747, recording the pid);
  • the stdout feedLine handler (queue.js:679/690, recording the session id);
  • stack-less Error: ENOSPC ... write, which matches an un-listened 'error' event on the job's stdout/stderr createWriteStream.

All three run in event handlers outside any try, so the error reaches the process-level handler and the server restarts.

Change

  • recordInHandler wraps those two store.update calls. On failure it keeps the patch in memory, logs could not record job state, and still emits job.updated.
  • The stdout and stderr streams get 'error' listeners (could not write job output). end() is skipped on a stream that has already been destroyed, so the attempt can't hang.
  • CHANGELOG entry under Unreleased.

Tests

  • New test JobQueue when the disk is full: the pid write throws ENOSPC and the job still succeeds, with the warning logged. It fails on main with the unhandled ENOSPC error.
  • Full suite: 63 files / 523 tests pass.
  • pnpm typecheck is clean.

The disk itself (other products' CI caches) is tracked separately in the operator's reliability backlog (RA-013).

🤖 Generated with Claude Code

The spawn handler (pid), the stdout line handler (session id) and the job's
stdout/stderr write streams ran outside any try. On a full disk their ENOSPC
reached the daemon's uncaught-exception handler; launchd restarted the server
and every restart interrupted the running jobs (18 restarts, 29 interrupted
jobs on 2026-11-11 03:49-06:00Z). Log those failures and keep the job going;
skip end() on a stream that already failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JOsacky
JOsacky merged commit f711faa into main Nov 11, 2026
6 checks passed
@JOsacky
JOsacky deleted the fix/daemon-enospc-crash branch November 11, 2026 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant