Skip to content

ProcessFdQuotaExceeded blocks all shell commands after repeated tool calls #253

Closed

Description

@pranavp311

After repeated review and shell-tool activity, every shell launch began failing before command execution with ProcessFdQuotaExceeded, including a minimal true command. File-reading tools continued to work, which isolated the failure to process/FD launch handling. The project smoke scripts install EXIT traps and reap their child processes. The condition persisted across both the root and delegated tool contexts, then cleared on a later turn without project-side cleanup. Attempts to inspect individual harness.trace.jsonl records returned StreamTooLong, so trace evidence could not be extracted.

Expected: process descriptors are reclaimed after each tool execution, and a trace reader can access bounded JSONL records.

Actual: all shell-based recovery and diagnostics were blocked until the condition cleared externally.

Activity

  1. justrach commented on Jul 24, 2026

    @justrach
    Owner

    Investigated. The fd-quota recovery machinery from #172 is present and works — src/tools.zig:361 special-cases error.ProcessFdQuotaExceeded with recovery guidance, and I mutation-tested read_file.zig to confirm the cited path is live rather than a false green.

    But I am not closing this, because the "already fixed" argument does not actually hold up on the timeline:

    So the reporter may well have been running a build that already had #172, which would make this a genuinely separate defect rather than a duplicate. The available version fingerprint bounds their build to pre-v0.0.207 but does not exclude v0.0.202–v0.0.206.

    @pranavp311 — which graff --version were you on? That settles it either way.

    One real gap found while looking: the recovery only covers error.ProcessFdQuotaExceeded (EMFILE, per-process). Zig 0.16's spawn error sets also include error.SystemFdQuotaExceeded (ENFILE, system-wide), which graff does not special-case — and the background-job branch emits actively wrong advice for it. That is worth fixing regardless of how the version question resolves.

  2. added 2 commits that reference this issue on Jul 31, 2026
  3. justrach commented on Jul 31, 2026

    @justrach
    Owner

    Partially addressed in v0.0.226 (PR #328) - leaving this open.

    Landed: The fd-quota failure now names the observed RLIMIT_NOFILE soft/hard limit at the failure site, so the next report can distinguish "the limit never rose" from "it rose and the fan-out still exhausted it". A descriptor high-water probe and a leak test around timed-out runs were added.

    Still open: whether the leak is fully closed is not yet proven in the wild - please reopen with the new [fd] line if it recurs.

  4. added a commit that references this issue on Aug 1, 2026
  5. justrach commented on Aug 1, 2026

    @justrach
    Owner

    Closing per the criterion stated in triage: the fd-leak fix, the [fd] spawn failed: … RLIMIT_NOFILE soft= hard= probe, and the timed-out-runs-don't-leak test all shipped in v0.0.226+ (src/process_runner.zig), and the last named code remainder — the actively wrong 'run it in the foreground' advice for SystemFdQuotaExceeded — is now fixed on main via #348: both tools.failure and the background-job spawn branch give system-wide exhaustion its own honest guidance (neither foregrounding nor ulimit helps), with a regression test covering all three advice paths. If this recurs on >= v0.0.226, please reopen with the new [fd] diagnostic line (and your graff version).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions