Skip to content

Conversation

@majiayu000
Copy link
Contributor

Summary

This PR fixes the root cause of issue #2242 where API block requests timeout at 5 minutes regardless of user-configured timeout settings.

Root Cause

Bun/Node.js fetch has a hardcoded 5-minute (300 seconds) default timeout that cannot be overridden by AbortSignal.timeout(). This is documented in Bun PR #6217.

Solution

  • Add timeout: false to all fetch calls to disable Bun/Node.js default 5-minute timeout
  • Use AbortSignal.timeout() for user-configurable timeout control (default: 2 min, max: 10 min)
  • Add maxDuration = 600 to /api/proxy and /api/workflows/[id]/execute routes for Next.js

Changes

File Changes
apps/sim/tools/index.ts Add parseTimeout() function, add timeout: false + AbortSignal.timeout() to handleInternalRequest and handleProxyRequest
apps/sim/app/api/proxy/route.ts Add maxDuration = 600 and timeout: false
apps/sim/app/api/workflows/[id]/execute/route.ts Add maxDuration = 600
apps/sim/tools/http/types.ts Add timeout?: number field to RequestParams

Test Results

Scenario Result
Without timeout: false + 6-min request ❌ Timeout at 5 minutes
With timeout: false + 6-min request ✅ Completed successfully after 6 minutes

Test Plan

  • Verified 6-minute API request completes successfully with timeout: false
  • Test in Sim.AI UI with API block configured for 10-minute timeout
  • Verify Docker deployment works with long-running requests

Closes #2242

🤖 Generated with Claude Code

Root cause: Bun/Node.js fetch has a hardcoded 5-minute (300s) default
timeout that cannot be overridden by AbortSignal.timeout().

Changes:
- Add parseTimeout() function to validate user-configurable timeouts
- Add timeout: false to all fetch calls to disable Bun's default limit
- Use AbortSignal.timeout() for user-configurable timeout control
- Add maxDuration=600 to /api/proxy and /api/workflows/[id]/execute routes
- Add timeout field to RequestParams interface

This allows API block requests to run up to 10 minutes as configured
by the user, fixing issue simstudioai#2242.

Tested: 6-minute API request completes successfully with timeout: false

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Dec 29, 2025

@majiayu000 is attempting to deploy a commit to the Sim Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Dec 29, 2025

Greptile Summary

Fixed the 5-minute timeout limit for API block requests by disabling Bun/Node.js default timeout and implementing user-configurable timeout control (2-10 minutes).

Key Changes:

  • Added parseTimeout() function to validate and clamp timeout values between 2-10 minutes
  • Applied timeout: false + AbortSignal.timeout() to handleInternalRequest and handleProxyRequest in tools/index.ts
  • Added maxDuration = 600 to /api/proxy and /api/workflows/[id]/execute routes for Next.js
  • Added timeout field to RequestParams type definition

Issues Found:

  • GET handler in /api/proxy/route.ts sets timeout: false but doesn't include AbortSignal.timeout(), creating inconsistent timeout behavior between GET and POST handlers

Confidence Score: 4/5

  • This PR is safe to merge with one logical fix needed for the GET handler
  • The core timeout fix is well-implemented with proper validation and documentation. However, the GET handler in apps/sim/app/api/proxy/route.ts is missing AbortSignal.timeout(), which creates inconsistent behavior - it has no timeout control except the route's maxDuration. This should be fixed to match the POST handlers' pattern of using both timeout: false and signal: AbortSignal.timeout().
  • apps/sim/app/api/proxy/route.ts GET handler needs AbortSignal.timeout() added for consistent timeout behavior

Important Files Changed

Filename Overview
apps/sim/tools/index.ts Added parseTimeout() function and timeout handling with timeout: false + AbortSignal.timeout() to both request handlers
apps/sim/app/api/proxy/route.ts Added maxDuration = 600 and timeout: false to GET handler, but missing AbortSignal for timeout control

Sequence Diagram

sequenceDiagram
    participant Client as API Block/Client
    participant ProxyRoute as /api/proxy
    participant ToolHandler as tools/index.ts
    participant ExternalAPI as External API
    
    Note over Client,ExternalAPI: User-configured timeout flow
    
    Client->>ProxyRoute: POST /api/proxy<br/>{toolId, params: {timeout: 600000}}
    Note over ProxyRoute: maxDuration = 600s<br/>(Next.js route config)
    
    ProxyRoute->>ToolHandler: executeTool(toolId, params)
    
    alt Internal Request Handler
        ToolHandler->>ToolHandler: parseTimeout(params.timeout)<br/>Returns: min(timeout, 600000ms)
        Note over ToolHandler: timeout: false<br/>signal: AbortSignal.timeout(timeoutMs)
        ToolHandler->>ExternalAPI: fetch(url, {timeout: false, signal})
        ExternalAPI-->>ToolHandler: Response (within timeout)
        ToolHandler-->>ProxyRoute: Success
    else Proxy Request Handler
        ToolHandler->>ToolHandler: parseTimeout(params.timeout)<br/>Returns: min(timeout, 600000ms)
        Note over ToolHandler: timeout: false<br/>signal: AbortSignal.timeout(timeoutMs)
        ToolHandler->>ProxyRoute: fetch(/api/proxy, {timeout: false, signal})
        ProxyRoute->>ExternalAPI: Forward request
        ExternalAPI-->>ProxyRoute: Response (within timeout)
        ProxyRoute-->>ToolHandler: Response
        ToolHandler-->>ProxyRoute: Success
    end
    
    ProxyRoute-->>Client: Response with result
    
    Note over Client,ExternalAPI: Timeout scenarios
    
    alt Timeout Exceeded
        ToolHandler->>ExternalAPI: fetch with AbortSignal
        Note over ExternalAPI: Request takes > timeoutMs
        ExternalAPI-xToolHandler: AbortError (signal timeout)
        ToolHandler-->>Client: Error: Request timed out
    end
    
    alt GET /api/proxy (Direct Proxy)
        Client->>ProxyRoute: GET /api/proxy?url=...
        Note over ProxyRoute: timeout: false<br/>NO AbortSignal!<br/>Relies only on maxDuration=600s
        ProxyRoute->>ExternalAPI: fetch(url, {timeout: false})
        ExternalAPI-->>ProxyRoute: Response
        ProxyRoute-->>Client: Response
    end
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Additional Comments (1)

  1. apps/sim/app/api/proxy/route.ts, line 224-234 (link)

    logic: GET handler missing AbortSignal.timeout() - only disables default timeout but provides no user-configurable timeout control

    The GET handler sets timeout: false but doesn't include signal: AbortSignal.timeout() like the POST handlers in tools/index.ts. This means requests have no timeout limit except the route's maxDuration of 600s, making timeout behavior inconsistent.

4 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

The @ts-expect-error directive fails in CI because it reports 'unused
directive' when the error doesn't exist in the Node.js type definitions.
Using @ts-ignore unconditionally ignores the type error, which is the
desired behavior for Bun-specific options.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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.

1 participant