Skip to content

DispatchAbortedError#cause attribution is worker-index order, not chronological #215

Description

@duncanita

Severity: low
Found in: 2026-07-22 code review

Location

lib/dag/effects/dispatcher.rb:216,224.

Failure mode

Among same-severity (StandardError) worker failures, the exception attached as DispatchAbortedError#cause is the one from the lowest-numbered worker, which is not necessarily the first failure in time — worker 0 may fail at t=50ms while worker 1 failed at t=5ms. Since the drain-and-join protocol deliberately lets in-flight peers finish, the relative completion order of failures is timing-dependent, so the reported cause (and the "dispatch tick aborted: #{message}" string) can flip between identical runs, weakening the determinism the report otherwise guarantees (slot-ordered outcomes). The serial path (serial_map) is chronological, so this is also a serial/parallel asymmetry.

Minimal trigger

parallelism: 2; both records' completions raise distinct StandardErrors with the later-started worker failing first; #cause is the lower-indexed worker's error regardless of which occurred first.

Fix direction

Timestamp or sequence-tag captured errors and pick the chronologically first; at minimum, prefer non-StandardError (which also fixes the companion medium-severity issue).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingeffectsEffect-aware kernel protocol and durable intent work

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions