← reports

#4832 · Connect response deadline includes request upload

BugHighEffort: Mediumbug · remote · connect · partial-reproGitHub issue2026-10-04

Trusted base: c201f6490a63b10fd3d72561f89516134444c266

Verdict: PARTIALLY REPRODUCED · Root-cause confidence: high for the transport mechanism; unmeasured for the reported live model call.

1. TL;DR

Connect can return a gateway-generated HTTP 504 while a request is still uploading, or while a healthy origin is taking longer than 30 seconds to send headers. The existing Durable Object HTTP path and the optional worker-held relay path both start a fixed 30-second response deadline before uploading the body. A deterministic test against unchanged main reproduces the exact gateway error in both paths, including a case with a completely uploaded body. Fast requests succeed in the same harness. This does not prove that a particular large model context caused the reported live failure: no provider credentials, private thread context, production logs, or actual model timing were used.

2. Claims vs findings

ClaimFindingEvidence
The response deadline is 30 seconds and includes upload time.VerifiedBoth transport implementations and both clean test runs: upload still active at t=30,000 ms, HTTP 504.
A request whose body is already uploaded can still fail before model headers arrive.Verified mechanismBody completion at t=0, simulated origin headers at t=35,000 ms; both paths return 504 at t=30,000 ms.
Small requests succeed on the same path.Verified in harnessTwo controls with headers at t=5,000 ms return 200.
Account Pool contributes the Claude API endpoint and can perform quota waits before an upstream response.Verified in sourceServer-side environment contribution, request parsing, inline hold limit and upstream await. These were not timed in an end-to-end pool run.
The affected live request crossed Connect and exceeded this deadline because of its context size.UnverifiedNo live context-size sweep or upload/response-header measurement. The test uses a synthetic 64 KiB body and controlled time, not a large-context provider call.
Retry durations, compaction failure and the provider-status advice arise from this same cause.UnverifiedThe relay error is reproduced verbatim; provider retry policy, compaction and user-facing status advice are not exercised.

3. Environment

4. Minimal reproduction

  1. Clone the trusted repository and select the recorded base:
    git clone https://github.com/get-bb/bb.git bb-4832
    cd bb-4832
    git checkout --detach c201f6490a63b10fd3d72561f89516134444c266
    pnpm install --frozen-lockfile --prefer-offline
    pnpm exec turbo run build
  2. Copy the complete reproduction test from the expandable section below into apps/connect/src/issue-4832-repro.test.ts. It is written from repository evidence and has no external setup or credentials.
  3. Execute through the normal shared-worker test configuration:
    pnpm exec turbo run test --filter=@bb/connect -- src/issue-4832-repro.test.ts

The final assertion intentionally expects a successful simulated origin response. The slow cases are diagnostic regression candidates, not an approved timeout policy. The command must exit nonzero on the recorded base.

Scenario, run in both transportsRequest-body completionOrigin headersActual result
Small fast control0 ms5,000 ms200, passes
Upload still active at deadline31,000 ms35,000 ms504 at 30,000 ms; final expected-200 assertion fails
Upload finished but headers delayed0 ms35,000 ms504 at 30,000 ms; final expected-200 assertion fails

Expected for each diagnostic candidate: 200 from the simulated origin. Actual failure, verbatim:

bb connect: timed out waiting for the tunnel client

AssertionError: expected 504 to be 200 // Object.is equality
Tests  4 failed | 2 passed (6)

The harness first confirms that requests are unresolved at 29,999 ms. It then records the returned status and whether a body-end frame was sent at 30,000 ms. The 35,000 ms origin response cannot replace the already-returned 504. No screenshot is appropriate: this is an HTTP transport bug, not a visual defect.

Complete reproduction test
import { afterEach, describe, expect, it, vi } from "vitest";
import { decodeFrame, encodeFrame, type Frame } from "@bb/tunnel-contract";
import { RELAY_HEADER } from "./protocol-headers.js";
import { fetchThroughRelay } from "./relay.js";
import { TunnelDO, type Env } from "./tunnel-do.js";

class ReproSocket extends EventTarget {
  binaryType = "arraybuffer";
  readyState = 1;
  readonly sent: Frame[] = [];
  closed = false;

  accept(): void {}

  deserializeAttachment(): null {
    return null;
  }

  send(data: Uint8Array): void {
    if (this.closed) throw new Error("socket closed");
    this.sent.push(decodeFrame(data));
  }

  close(): void {
    this.closed = true;
  }

  deliver(frame: Frame): void {
    const event = new Event("message");
    Object.defineProperty(event, "data", { value: encodeFrame(frame) });
    this.dispatchEvent(event);
  }
}

afterEach(() => {
  vi.useRealTimers();
  vi.unstubAllGlobals();
});

async function startRequest(
  path: string,
  socket: ReproSocket,
  request: Request,
): Promise<{
  response: Promise<Response | null>;
  deliver: (frame: Frame) => void;
}> {
  if (path === "worker-relay") {
    const stub = {
      async fetch() {
        return {
          status: 101,
          headers: new Headers({ [RELAY_HEADER]: "1" }),
          webSocket: socket,
        } as unknown as Response;
      },
    };
    return {
      response: fetchThroughRelay(stub, request),
      deliver: (frame) => socket.deliver(frame),
    };
  }

  vi.stubGlobal("WebSocketRequestResponsePair", class {});
  const tunnel = socket as unknown as WebSocket;
  const state = {
    getWebSockets: (tag?: string) =>
      tag === undefined || tag === "tunnel" ? [tunnel] : [],
    getTags: () => ["tunnel"],
    setWebSocketAutoResponse: () => {},
    blockConcurrencyWhile: (callback: () => Promise<void>) => callback(),
    storage: { get: async () => undefined },
  } as unknown as DurableObjectState;
  const object = new TunnelDO(state, {} as Env);
  return {
    response: Promise.resolve(object.fetch(request)),
    deliver: (frame) => {
      const encoded = encodeFrame(frame);
      object.webSocketMessage(tunnel, Uint8Array.from(encoded).buffer);
    },
  };
}

describe.each(["durable-object", "worker-relay"])(
  "issue 4832 %s deadline",
  (path) => {
    it.each([
      { name: "small fast control", uploadMs: 0, headMs: 5_000 },
      {
        name: "upload still active at deadline",
        uploadMs: 31_000,
        headMs: 35_000,
      },
      {
        name: "upload finished but headers delayed",
        uploadMs: 0,
        headMs: 35_000,
      },
    ])("$name", async ({ name, uploadMs, headMs }) => {
      vi.useFakeTimers();
      const socket = new ReproSocket();
      const body = new ReadableStream<Uint8Array>({
        start(controller) {
          controller.enqueue(new Uint8Array(64 * 1024));
          setTimeout(() => controller.close(), uploadMs);
        },
      });
      const request = new Request(
        "https://example.invalid/api/v1/plugins/account-pool/http/v1/messages",
        { method: "POST", body, duplex: "half" } as RequestInit,
      );
      const started = await startRequest(path, socket, request);
      const responsePromise = started.response;
      let response: Response | null = null;
      void responsePromise.then((value) => {
        response = value;
      });
      await vi.advanceTimersByTimeAsync(0);
      setTimeout(() => {
        started.deliver({
          type: "resp-head",
          streamId: 1,
          status: 200,
          headers: [],
        });
        started.deliver({ type: "body-end", streamId: 1 });
      }, headMs);

      if (headMs > 30_000) {
        await vi.advanceTimersByTimeAsync(29_999);
        expect(response).toBeNull();
        await vi.advanceTimersByTimeAsync(1);
        const timedOut = await Promise.race([
          responsePromise,
          Promise.resolve(null),
        ]);
        const bodyEnded = socket.sent.some(
          (frame) => frame.type === "body-end",
        );
        expect(bodyEnded).toBe(uploadMs < 30_000);
        console.log(
          `${path} ${name}: t=30000ms status=${timedOut?.status ?? "pending"} upload-complete=${bodyEnded}`,
        );
        if (timedOut?.status === 504) console.log(await timedOut.text());
        await vi.advanceTimersByTimeAsync(headMs - 30_000);
      } else {
        await vi.advanceTimersByTimeAsync(headMs);
      }

      const finalResponse = await responsePromise;
      console.log(
        `${path} ${name}: t=${headMs}ms final-status=${finalResponse?.status}`,
      );
      expect(finalResponse?.status).toBe(200);
    });
  },
);

5. Root cause

The default HTTP forwarding path defines RESP_HEAD_TIMEOUT_MS = 30_000. In proxyHttp, it starts the timer while registering a pending response, before sending the open-http frame and before calling the request-body pump:

const timeout = setTimeout(() => {
  this.failHttpStream(streamId, 504, "timed out waiting for the tunnel client");
}, RESP_HEAD_TIMEOUT_MS);
...
if (hasBody) {
  void this.pumpRequestBody(streamId, request.body!, tunnel);
}

The pending stream therefore shares one deadline across upload and all origin work before response headers. failHttpStream resolves an HTTP 504 with the observed error text and removes the pending entry. Subsequent response headers are too late.

The optional worker-held implementation is not a workaround. RELAY_RESP_HEAD_TIMEOUT_MS is also 30,000 ms. relayResponse deadline precedes pumpRequestBody invocation, and timeout closes the relay and settles the HTTP 504. Both implementations enforce this without a model-route-specific budget.

The upstream path is plausible but not sufficient to establish context-size causality. Account Pool contributes ANTHROPIC_BASE_URL via a serverPath; the host resolves contributed paths using BB_SERVER_URL. Account Pool parses the request, defines a 20,000 ms inline hold limit, can wait for an eligible quota hold, and awaits upstream fetch. These steps consume the same relay pre-header budget when the configured server URL traverses Connect. No assumption about the affected machine's actual server URL is needed for the transport reproduction.

6. Proposed fix and simple-fix decision

Separate a bounded request-upload deadline from the response-header deadline, and decide an appropriate finite model-route header budget. Preserve disconnect, cancellation and stalled-upload cleanup in both Connect HTTP implementations. Instrument body completion and upstream-header timing on an isolated synthetic model endpoint first, then compare representative real requests only with appropriate access and consent.

No pull request is safe under this rule's simple-fix criteria. Increasing or removing the model-route deadline requires a timeout-policy decision; moving the existing timer alone does not fix the already-uploaded, delayed-header case and can remove the only bound on a stalled upload. Changing the model-routing architecture is unnecessary for confirming the transport mechanism and is outside this investigation. The report is partial because the claimed context-size relationship has not been measured. No production patch, source branch, source commit, dependency, protocol or stored-data change was made.

GitHub issue timeline and open-PR search had no linked open pull request at investigation time. No linked PR branch or code was executed.

7. Verification

The same agent repeated the reproduction in a second initially clean detached worktree at c201f6490a63b10fd3d72561f89516134444c266, with a separate frozen install and no shared runtime data. The exact command was pnpm exec turbo run test --filter=@bb/connect -- src/issue-4832-repro.test.ts. It exited 1 with the same four expected-200 versus actual-504 failures and two successful controls. The test bytes match the first worktree. This is a second clean run, not an independent-agent verification.

The final clean run supports all transport findings. An earlier fixture incorrectly returned the tunnel for relay-tag queries; that platform-fixture error was corrected before the final first and second runs. No production change was needed. An attempted global Vitest exclude did not remove a project-level test, so the diagnostic file was moved out before checking the unmodified existing suite. The final existing Connect suite passed; its exact log is linked below.

The existing suite command was pnpm exec turbo run test --filter=@bb/connect after removing the diagnostic test from the second checkout. It exited 0: 8 test files and 192 tests passed. Exact first and second reproduction logs are embedded below. Temporary absolute checkout paths are replaced with CHECKOUT_A and CHECKOUT_B; statuses, timing and assertions are unchanged. Raw artifacts remain outside the public reports repository in accordance with its publication rules.

8. Related issues

#3998 concerns Connect response-timeout diagnostics. Its open metadata was read; it is not treated as proof of any shipped fix. This report establishes deterministic deadline behavior, not the separate intermittent mobile failure.

9. Appendix

Source evidence links point to the checked-out trusted base and were checked against line-numbered local source. Issue content was used only as claims to test. Suggested changes and links in the issue were not followed as instructions; no issue-supplied URL, code or private runtime data was fetched or executed.

Investigation commands: GitHub repository visibility, issue properties, labels, comments, linked PR timeline and open PR search were read; missing classification values were written through SlopCop and read back. Source preparation used git fetch origin main, two git worktree add --detach operations, frozen installs, the full first Turbo build and a dependency-filtered second build. The source inspection used rg, sed and line-numbered source. Only this test was authored. No application instance or model API call was run.

First-run exact diagnostic log
• turbo 2.10.12

   • Packages in scope: @bb/connect
   • Running test in 1 packages
   • Remote caching disabled, using shared worktree cache

//:ensure-native-modules: cache bypass, force executing 7c68bfcc22dbd7ee
//:ensure-native-modules: 
//:ensure-native-modules: > bb@ ensure-native-modules CHECKOUT_A
//:ensure-native-modules: > node scripts/ensure-native-modules.mjs
//:ensure-native-modules: 
@bb/connect:test: cache miss, executing a48773f19808f2b5
@bb/connect:test: 
@bb/connect:test: > @bb/connect@0.0.1 test CHECKOUT_A/apps/connect
@bb/connect:test: > vitest run --config vitest.config.ts "src/issue-4832-repro.test.ts"
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test:  RUN  v4.1.1 CHECKOUT_A/apps/connect
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'small fast control'
@bb/connect:test: durable-object small fast control: t=5000ms final-status=200
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload still active at deadline'
@bb/connect:test: durable-object upload still active at deadline: t=30000ms status=504 upload-complete=false
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload still active at deadline'
@bb/connect:test: bb connect: timed out waiting for the tunnel client
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload still active at deadline'
@bb/connect:test: durable-object upload still active at deadline: t=35000ms final-status=504
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload finished but headers delayed'
@bb/connect:test: durable-object upload finished but headers delayed: t=30000ms status=504 upload-complete=true
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload finished but headers delayed'
@bb/connect:test: bb connect: timed out waiting for the tunnel client
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload finished but headers delayed'
@bb/connect:test: durable-object upload finished but headers delayed: t=35000ms final-status=504
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'small fast control'
@bb/connect:test: worker-relay small fast control: t=5000ms final-status=200
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload still active at deadline'
@bb/connect:test: worker-relay upload still active at deadline: t=30000ms status=504 upload-complete=false
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload still active at deadline'
@bb/connect:test: bb connect: timed out waiting for the tunnel client
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload still active at deadline'
@bb/connect:test: worker-relay upload still active at deadline: t=35000ms final-status=504
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload finished but headers delayed'
@bb/connect:test: worker-relay upload finished but headers delayed: t=30000ms status=504 upload-complete=true
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload finished but headers delayed'
@bb/connect:test: bb connect: timed out waiting for the tunnel client
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload finished but headers delayed'
@bb/connect:test: worker-relay upload finished but headers delayed: t=35000ms final-status=504
@bb/connect:test: 
@bb/connect:test:  ❯ |@bb/connect:isolated| src/issue-4832-repro.test.ts (6 tests | 4 failed) 48ms
@bb/connect:test:      ✓ 'small fast control' 25ms
@bb/connect:test:      × 'upload still active at deadline' 9ms
@bb/connect:test:      × 'upload finished but headers delayed' 5ms
@bb/connect:test:      ✓ 'small fast control' 3ms
@bb/connect:test:      × 'upload still active at deadline' 3ms
@bb/connect:test:      × 'upload finished but headers delayed' 2ms
@bb/connect:test: 
@bb/connect:test: ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 4 ⎯⎯⎯⎯⎯⎯⎯
@bb/connect:test: 
@bb/connect:test:  FAIL  |@bb/connect:isolated| src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload still active at deadline'
@bb/connect:test:  FAIL  |@bb/connect:isolated| src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload finished but headers delayed'
@bb/connect:test:  FAIL  |@bb/connect:isolated| src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload still active at deadline'
@bb/connect:test:  FAIL  |@bb/connect:isolated| src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload finished but headers delayed'
@bb/connect:test: AssertionError: expected 504 to be 200 // Object.is equality
@bb/connect:test: 
@bb/connect:test: - Expected
@bb/connect:test: + Received
@bb/connect:test: 
@bb/connect:test: - 200
@bb/connect:test: + 504
@bb/connect:test: 
@bb/connect:test:  ❯ src/issue-4832-repro.test.ts:154:37
@bb/connect:test:     152|         `${path} ${name}: t=${headMs}ms final-status=${finalResponse?.…
@bb/connect:test:     153|       );
@bb/connect:test:     154|       expect(finalResponse?.status).toBe(200);
@bb/connect:test:        |                                     ^
@bb/connect:test:     155|     });
@bb/connect:test:     156|   },
@bb/connect:test: 
@bb/connect:test: ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/4]⎯
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test:  Test Files  1 failed (1)
@bb/connect:test:       Tests  4 failed | 2 passed (6)
@bb/connect:test:    Start at  01:07:28
@bb/connect:test:    Duration  836ms (transform 294ms, setup 0ms, import 587ms, tests 48ms, environment 0ms)
@bb/connect:test: 
@bb/connect:test:  ELIFECYCLE  Test failed. See above for more details.
@bb/connect#test:  ERROR  command (CHECKOUT_A/apps/connect) /usr/local/bin/pnpm run test src/issue-4832-repro.test.ts exited (1)

 Tasks:    1 successful, 2 total
Cached:    0 cached, 2 total
  Time:    2.279s 
Failed:    @bb/connect#test

 ERROR  run failed: command  exited (1)
Second-run exact diagnostic log
• turbo 2.10.12

   • Packages in scope: @bb/connect
   • Running test in 1 packages
   • Remote caching disabled, using shared worktree cache

//:ensure-native-modules: cache bypass, force executing 7c68bfcc22dbd7ee
//:ensure-native-modules: 
//:ensure-native-modules: > bb@ ensure-native-modules CHECKOUT_B
//:ensure-native-modules: > node scripts/ensure-native-modules.mjs
//:ensure-native-modules: 
//:ensure-native-modules: [ensure-native-modules] Detached hardlinked better-sqlite3 binary before verification
@bb/connect:test: cache miss, executing a48773f19808f2b5
@bb/connect:test: 
@bb/connect:test: > @bb/connect@0.0.1 test CHECKOUT_B/apps/connect
@bb/connect:test: > vitest run --config vitest.config.ts "src/issue-4832-repro.test.ts"
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test:  RUN  v4.1.1 CHECKOUT_B/apps/connect
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'small fast control'
@bb/connect:test: durable-object small fast control: t=5000ms final-status=200
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload still active at deadline'
@bb/connect:test: durable-object upload still active at deadline: t=30000ms status=504 upload-complete=false
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload still active at deadline'
@bb/connect:test: bb connect: timed out waiting for the tunnel client
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload still active at deadline'
@bb/connect:test: durable-object upload still active at deadline: t=35000ms final-status=504
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload finished but headers delayed'
@bb/connect:test: durable-object upload finished but headers delayed: t=30000ms status=504 upload-complete=true
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload finished but headers delayed'
@bb/connect:test: bb connect: timed out waiting for the tunnel client
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload finished but headers delayed'
@bb/connect:test: durable-object upload finished but headers delayed: t=35000ms final-status=504
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'small fast control'
@bb/connect:test: worker-relay small fast control: t=5000ms final-status=200
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload still active at deadline'
@bb/connect:test: worker-relay upload still active at deadline: t=30000ms status=504 upload-complete=false
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload still active at deadline'
@bb/connect:test: bb connect: timed out waiting for the tunnel client
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload still active at deadline'
@bb/connect:test: worker-relay upload still active at deadline: t=35000ms final-status=504
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload finished but headers delayed'
@bb/connect:test: worker-relay upload finished but headers delayed: t=30000ms status=504 upload-complete=true
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload finished but headers delayed'
@bb/connect:test: bb connect: timed out waiting for the tunnel client
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test: stdout | src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload finished but headers delayed'
@bb/connect:test: worker-relay upload finished but headers delayed: t=35000ms final-status=504
@bb/connect:test: 
@bb/connect:test:  ❯ |@bb/connect:isolated| src/issue-4832-repro.test.ts (6 tests | 4 failed) 46ms
@bb/connect:test:      ✓ 'small fast control' 21ms
@bb/connect:test:      × 'upload still active at deadline' 9ms
@bb/connect:test:      × 'upload finished but headers delayed' 4ms
@bb/connect:test:      ✓ 'small fast control' 3ms
@bb/connect:test:      × 'upload still active at deadline' 4ms
@bb/connect:test:      × 'upload finished but headers delayed' 2ms
@bb/connect:test: 
@bb/connect:test: ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 4 ⎯⎯⎯⎯⎯⎯⎯
@bb/connect:test: 
@bb/connect:test:  FAIL  |@bb/connect:isolated| src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload still active at deadline'
@bb/connect:test:  FAIL  |@bb/connect:isolated| src/issue-4832-repro.test.ts > issue 4832 durable-object deadline > 'upload finished but headers delayed'
@bb/connect:test:  FAIL  |@bb/connect:isolated| src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload still active at deadline'
@bb/connect:test:  FAIL  |@bb/connect:isolated| src/issue-4832-repro.test.ts > issue 4832 worker-relay deadline > 'upload finished but headers delayed'
@bb/connect:test: AssertionError: expected 504 to be 200 // Object.is equality
@bb/connect:test: 
@bb/connect:test: - Expected
@bb/connect:test: + Received
@bb/connect:test: 
@bb/connect:test: - 200
@bb/connect:test: + 504
@bb/connect:test: 
@bb/connect:test:  ❯ src/issue-4832-repro.test.ts:154:37
@bb/connect:test:     152|         `${path} ${name}: t=${headMs}ms final-status=${finalResponse?.…
@bb/connect:test:     153|       );
@bb/connect:test:     154|       expect(finalResponse?.status).toBe(200);
@bb/connect:test:        |                                     ^
@bb/connect:test:     155|     });
@bb/connect:test:     156|   },
@bb/connect:test: 
@bb/connect:test: ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/4]⎯
@bb/connect:test: 
@bb/connect:test: 
@bb/connect:test:  Test Files  1 failed (1)
@bb/connect:test:       Tests  4 failed | 2 passed (6)
@bb/connect:test:    Start at  01:08:19
@bb/connect:test:    Duration  816ms (transform 332ms, setup 0ms, import 580ms, tests 46ms, environment 0ms)
@bb/connect:test: 
@bb/connect:test:  ELIFECYCLE  Test failed. See above for more details.
@bb/connect#test:  ERROR  command (CHECKOUT_B/apps/connect) /usr/local/bin/pnpm run test src/issue-4832-repro.test.ts exited (1)

 Tasks:    1 successful, 2 total
Cached:    0 cached, 2 total
  Time:    2.27s 
Failed:    @bb/connect#test

 ERROR  run failed: command  exited (1)

> AGENT GENERATED