Skip to content

fix(tools): bound internal tool calls by the plan deadline, not Bun's fetch default - #6547

Merged
icecrasher321 merged 3 commits into
stagingfrom
fix/fetch-timeout
Aug 11, 2026
Merged

fix(tools): bound internal tool calls by the plan deadline, not Bun's fetch default#6547
icecrasher321 merged 3 commits into
stagingfrom
fix/fetch-timeout

Conversation

@icecrasher321

Copy link
Copy Markdown
Collaborator

Summary

Every internal tool call was capped at 5 minutes regardless of plan.

tools/index.ts computes a plan-aware deadline for internal routes — getMaxExecutionTimeout(), 3000s on enterprise — and hands it to its own AbortController. It never handed it to the transport. So Bun's fetch idle timer governed instead, and its default is 300s.

Bun's own source describes that timer as re-arming on writes and body-phase reads but not on response-header reads, making it "an absolute deadline for the header block to complete." An AbortSignal cannot raise it. Any route that computes before it answers therefore dies at five minutes no matter what deadline was computed for it.

Reproduced in production on a workflow whose Function block runs a 15–40 minute sandboxed engine: all 16 parallel shards failed together at 300.5s with a bare fetch failed. An earlier run of the same workflow failed at 250.9s with TimeoutError: The operation timed out.

Type of Change

  • Bug fix

Testing

N/A

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercelBot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
docsSkippedSkippedAug 11, 2026 6:59pm

Request Review

@cursor

cursorBot commented Aug 11, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches the core internal tool HTTP path and timeout behavior for all internal routes on Bun; incorrect deadline mapping could cause hangs or premature failures, but behavior is covered by unit tests and Node is documented as ignoring the option.

Overview
Fixes long internal tool runs (e.g. Function blocks) dying at ~5 minutes even when the executor already computed a much larger plan timeout. Bun’s fetch idle timer defaults to 300s and is not raised by AbortSignal alone; only the in-process abort was wired before.

Adds withFetchDeadline to set Bun’s timeout on RequestInit to match the same deadlineMs used for the local AbortController (or timeout: false when there is no valid positive deadline, so the runtime does not silently keep the 300s default). Adds isTransportTimeoutError to recognize Bun’s opaque TimeoutError / fetch failed cases.

Internal route requests in tools/index.ts wrap fetch with withFetchDeadline(..., timeout) and, on transport timeout, rethrow with tool id, elapsed time, and deadline while preserving the original message for retry classification.

Reviewed by Cursor Bugbot for commit 0f421b1. Configure here.

@greptile-apps

greptile-appsBot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR prevents Bun’s default transport timeout from undercutting the plan-aware deadline on internal tool requests.

  • Adds a request-init helper that disables Bun’s transport timer while preserving the caller-owned abort signal.
  • Annotates recognized transport failures with the tool ID, elapsed time, and configured deadline.
  • Adds unit coverage for request-init preservation and transport-timeout recognition.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

FilenameOverview
apps/sim/lib/core/utils/fetch-deadline.tsIntroduces a focused helper for disabling Bun’s transport timeout and a classifier for recognized transport failures.
apps/sim/lib/core/utils/fetch-deadline.test.tsCovers helper output, immutability, init preservation, and timeout-error classification.
apps/sim/tools/index.tsApplies the helper to internal tool requests while retaining the existing AbortController deadline and adds contextual transport errors.

Sequence Diagram

sequenceDiagram
participant Executor as Tool executor
participant Timer as Plan deadline timer
participant Fetch as Bun fetch
participant Route as Internal route
Executor->>Timer: Arm AbortController with plan-aware timeout
Executor->>Fetch: "Request with signal and timeout=false"
Fetch->>Route: Internal tool request
alt Route responds before deadline
Route-->>Fetch: Response
Fetch-->>Executor: Tool response
else Plan deadline expires
Timer->>Fetch: Abort signal
Fetch-->>Executor: AbortError
else Transport fails
Fetch-->>Executor: TimeoutError or fetch failed
Executor->>Executor: Add tool, elapsed-time, and deadline context
end
Loading

Reviews (2): Last reviewed commit: "fix(tools): disarm Bun's fetch idle time..." | Re-trigger Greptile

Comment threadapps/sim/lib/core/utils/fetch-deadline.ts Outdated
icecrasher321and others added 2 commits August 11, 2026 11:25
…c deadline
Bun 1.3.14 ignores a positive numeric `timeout` on fetch and honors only the
boolean/zero form, so passing the plan deadline through changed nothing and
internal tool calls still died at the 300s default. Verified against the pinned
runtime: `{ timeout: 1000 }` does not abort a request that takes 3s to answer,
and `BUN_CONFIG_HTTP_IDLE_TIMEOUT` has no effect either — both are `main`-only.
The caller on this path already arms an AbortController with the plan timeout,
so the transport timer is disarmed rather than re-negotiated, leaving one
enforcement point instead of two that disagree.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@icecrasher321

Copy link
Copy Markdown
CollaboratorAuthor

@greptile

@icecrasher321

Copy link
Copy Markdown
CollaboratorAuthor

@cursor review

@cursorcursorBot 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 3d10803. Configure here.

Replaces the inferred note with the numbers from a probe against the pinned
runtime: no option dies at 300028ms, timeout:false survives 310031ms, and a
numeric timeout is ignored. Also records that bun-types@1.3.14 does not declare
the option even though the runtime honors it, which is why the interface is
declared locally.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@icecrasher321
icecrasher321 merged commit df052ac into stagingAug 11, 2026
21 checks passed
@waleedlatif1
waleedlatif1 deleted the fix/fetch-timeout branch August 11, 2026 21:55
Sign up for freeto 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.

1 participant

@icecrasher321