Skip to content

Conversation

@wewelll
Copy link
Contributor

@wewelll wewelll commented Jan 9, 2026

Summary

Fixes #5968

  • Fix causeResponse to pre-compute whether clientAbortFiberId exists anywhere in the cause tree before traversing individual interrupt nodes
  • When a client disconnects and the cause tree contains multiple interrupt entries, the server now correctly returns 499 instead of 503

The Bug

In causeResponse, the original code checked cause.fiberId === clientAbortFiberId on each interrupt node during Cause.reduce traversal. This fails when the cause tree has a structure like:

Sequential(Interrupt(parentFiberId), Interrupt(clientAbortFiberId))

Because Cause.reduce visits the left branch first, it encounters parentFiberId before clientAbortFiberId and incorrectly returns 503.

The Fix

Pre-compute whether clientAbortFiberId exists anywhere in the cause tree using Cause.interruptors() before entering the reduce loop:

const isClientAbort = HashSet.has(Cause.interruptors(cause), clientAbortFiberId)

Then use this flag when handling interrupt nodes instead of checking the individual node's fiber ID.

Test

The test constructs a synthetic cause that mimics the problematic structure:

const parentFiberId = yield* Effect.fiberId
const childInterrupt = Cause.interrupt(parentFiberId)
const clientAbortInterrupt = Cause.interrupt(HttpServerError.clientAbortFiberId)
const cause = Cause.sequential(childInterrupt, clientAbortInterrupt)
const [response] = yield* HttpServerError.causeResponse(cause)
expect(response.status).toEqual(499)

Note: Effect's runtime properly propagates interrupt IDs to child fibers, so real HTTP tests with nested fibers don't reproduce this specific cause structure. The synthetic test directly exercises causeResponse with the problematic cause tree.

@wewelll wewelll requested a review from tim-smart as a code owner January 9, 2026 13:21
@github-project-automation github-project-automation bot moved this to Discussion Ongoing in PR Backlog Jan 9, 2026
@changeset-bot
Copy link

changeset-bot bot commented Jan 9, 2026

🦋 Changeset detected

Latest commit: d14743b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 31 packages
Name Type
@effect/platform Patch
@effect/cli Patch
@effect/cluster Patch
@effect/experimental Patch
@effect/opentelemetry Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/rpc Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-drizzle Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-node Patch
@effect/sql Patch
@effect/workflow Patch
@effect/ai Patch
@effect/ai-amazon-bedrock Patch
@effect/ai-anthropic Patch
@effect/ai-google Patch
@effect/ai-openai Patch
@effect/ai-openrouter Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/sql-kysely Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@wewelll wewelll force-pushed the fix/http-server-client-abort-nested-fibers branch 3 times, most recently from 50bb6d9 to bd24a8b Compare January 9, 2026 13:37
…ng nested fiber execution

When a client disconnects and the request handler has child fibers, the server
would incorrectly return 503 because causeResponse only checked the first
interrupt encountered in Cause.reduce traversal. The fix now checks if
clientAbortFiberId exists anywhere in the entire cause tree's interruptors
before entering the reduce loop.

Added test case that verifies the fix by constructing a cause with multiple
interrupts where the child fiber's interrupt appears before the client abort.
@wewelll wewelll force-pushed the fix/http-server-client-abort-nested-fibers branch from bd24a8b to d14743b Compare January 9, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Discussion Ongoing

Development

Successfully merging this pull request may close these issues.

HTTP server returns 503 instead of 499 when client disconnects during nested fiber execution

1 participant