apache/shenyu · error · RuntimeException

Tool execution timeout or error

Error message

Tool execution timeout or error: ${e.getMessage()}

What it means

executeToolCall performs the decorated downstream exchange for the tool, often with a timeout guard. If execution throws or times out, it cleans up temporary MCP sessions and rethrows as RuntimeException('Tool execution timeout or error: ...'). It distinguishes the execution phase failure from earlier setup failures in call().

Solutions

  1. Inspect the wrapped cause: TimeoutException means increase the tool execution timeout or speed up the backend; IOException means connectivity.
  2. Verify the target service is up and the gateway route (selector/rule) matches the configured path.
  3. Increase the MCP tool execution timeout configuration for slow backends.
  4. Retest with a simple tool call to isolate whether the failure is tool-specific.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    return callback.call(args, ctx);
} catch (RuntimeException e) {
    Throwable c = e.getCause();
    if (c instanceof java.util.concurrent.TimeoutException) {
        // raise timeout or return graceful 'tool too slow' response
    } else if (c instanceof java.io.IOException) {
        // backend unreachable: check service health, maybe retry
    }
    throw e;
}

Prevention

When it happens

Trigger: The reactive tool execution inside executeToolCall times out or the downstream HTTP call errors (connection refused, 5xx, blocked selector/rule), while a valid session and config were already established.

Common situations: Backend service behind the gateway is down or slow; configured timeout too short for a long-running tool; wrong path in requestConfig leading to 404/500 from the gateway itself.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/83eeaaf2da2abc49. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallback.java:282

                    }
                })
                .subscribe();

        // Wait for the response with timeout
        try {
            final String result = responseFuture.get(DEFAULT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
            LOG.debug("Tool call completed successfully for session: {}", sessionId);
            return result;
        } catch (Exception e) {
            LOG.error("Timeout or error waiting for response for session {}: {}", sessionId, e.getMessage(), e);

            // Ensure cleanup on error for temporary sessions
            if (isTemporarySession) {
                LOG.debug("Emergency cleanup of temporary session on error: {}", sessionId);
                ShenyuMcpExchangeHolder.remove(sessionId);
            }

            throw new RuntimeException("Tool execution timeout or error: " + e.getMessage(), e);
        }
    }

    /**
     * Builds a decorated ServerWebExchange for tool execution.
     * <p>Creates a new exchange with modified request (method, path, headers, body),
     * response decorator based on protocol type, and updated Shenyu context and metadata.</p>
     *
     * @param originExchange the original exchange
     * @param responseFuture the future for capturing response
     * @param sessionId      the session identifier
     * @param configStr      the request configuration
     * @param input          the tool input parameters
     * @return the decorated exchange ready for execution
     */
    private ServerWebExchange buildDecoratedExchange(final ServerWebExchange originExchange,
                                                     final CompletableFuture<String> responseFuture,
                                                     final String sessionId,

View on GitHub (pinned to 567142e072)