Skip to content

console: the gateway proxy waits as long as it declares, not undici's five minutes - #214

Open
sakurahello1 wants to merge 1 commit into
HarnessRouter:mainfrom
sakurahello1:fix/bff-proxy-headers-timeout
Open

sakurahello1 wants to merge 1 commit into
HarnessRouter:mainfrom
sakurahello1:fix/bff-proxy-headers-timeout

Conversation

@sakurahello1

Copy link
Copy Markdown
Contributor

What

ui/src/app/api/harness/[...path]/route.ts declares maxDuration = 800, but the fetch it makes to the gateway was bounded by undici's defaults instead: 300 s for the response headers and 300 s between body chunks, then fetch failed, which the route turns into 502 harness-gateway unreachable. A synchronous POST /v1/responses sends nothing until the turn ends, so every turn longer than five minutes came back 502 through the console's API path while the runner finished it; a streamed turn silent for five minutes inside one tool call would end the same way. The gateway's own hop to the runner reads for an hour on purpose (httpx.Timeout(read=3600), "a long agent turn … never be cut off"), so this hop was the only one with a five-minute ceiling, and it was not a chosen one.

The proxy now dispatches through an undici Agent whose headersTimeout and bodyTimeout are maxDuration — one number, the one the route already declares.

How this showed up

Running a task slice through a self-hosted CE (0.18.x) over http://localhost:3000/api/harness: 4 of 20 synchronous turns came back 502 {"detail":"harness-gateway unreachable: fetch failed"} at 301.0 s, 300.3 s, and twice more, while GET /v1/sessions showed the same sessions done at 340 s, 354 s, 444 s and 425 s with their files and usage stored. The client had to find the session by hand to grade the turn.

Measured

  • Node 22's fetch against a stub that answers after 305 s: fetch failed | cause: UND_ERR_HEADERS_TIMEOUT Headers Timeout Error at 300.8 s.

  • The built console (standalone output) proxying to a stub gateway that answers after 305 s, same machine, same request:

    build result
    before {"detail":"harness-gateway unreachable: fetch failed"} HTTP 502 at 307.8 s
    after {"ok":true} HTTP 200 at 305.0 s

Notes

  • undici ^6.28.1 is added to the console's dependencies: the 6.x line is what Node 22 carries itself (the image's Node 22.23.2 reports undici 6.28.0), so the Agent speaks the dispatch interface the built-in fetch calls; Node 20 in CI is inside 6.x's support range. Webpack bundles it into the route chunk, so the standalone output needs no extra tracing.
  • The existing (init as RequestInit & { duplex: 'half' }).duplex = 'half' cast no longer type-checks once init carries dispatcher; duplex moved into init's declared type. No behaviour change there.
  • No jest test: the console has none yet (per tests.yml's note), and the first test file brings the jest configuration with it, which is not this change. npm run type-check and npm run build pass.

… five minutes

The BFF's maxDuration says 800 s, but the fetch it makes to the gateway was bounded by
undici's defaults: 300 s for the response headers and 300 s between body chunks, then
"fetch failed". A synchronous POST /v1/responses sends nothing until the turn ends, so a
turn longer than five minutes came back 502 "harness-gateway unreachable" while the runner
finished it — 301.0 s and 300.3 s on turns the session store shows completing at 340 s and
354 s — and a streamed turn silent for five minutes inside one tool call would end the same
way. The gateway's own hop to the runner reads for an hour on purpose.

The proxy now dispatches through an undici Agent whose headers and body timeouts are
maxDuration. Measured on the built console against a stub gateway that answers after
305 s: before, 502 "fetch failed" at 307.8 s; after, 200 at 305.0 s. undici 6.x is the
line Node 22 carries itself, so the Agent speaks the interface the built-in fetch calls.
Copilot AI lite review requested due to automatic review settings September 18, 2026 09:46
@vercel

vercel Bot commented Sep 18, 2026

Copy link
Copy Markdown

@sakurahello1 is attempting to deploy a commit to the Future HR Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The timeout alignment and dependency updates have no unresolved blocking issues.

Pull request overview

Updates the Harness Gateway proxy to honor its declared 800-second duration instead of Undici’s five-minute defaults.

Changes:

  • Configures extended header and body timeouts through an Undici Agent.
  • Adds and locks the undici dependency.
File summaries
File Description
ui/src/app/api/harness/[...path]/route.ts Applies extended upstream timeouts.
ui/package.json Adds the undici dependency.
ui/package-lock.json Locks the dependency and integrity data.
Review details

Files not reviewed (1)

  • ui/package-lock.json: Generated file
  • Files reviewed: 2/3 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

2 participants