paperclipai/paperclip · error · ToolGatewayHttpError

error.reasonCode

error.reasonCode

Error message

error.message

What it means

This is the generic rethrow branch for ToolGatewayHttpError inside the remote tools/call handler: the existing error is rewrapped preserving status, message, and reasonCode while enriching details with the current execution record (error.details.execution ?? execution) and the connection/catalog context. Like error 493, message and code are dynamic and mirror the original thrown ToolGatewayHttpError.

Solutions

  1. Inspect error.reasonCode and error.details (connectionId, catalogEntryId, execution) to find the root cause instead of the generic message.
  2. Fix the underlying issue indicated by the reason code (config, credentials, handle, or endpoint).
  3. Use the attached execution record to see request endpoint/protocol and how far the call progressed.
  4. Retry only for transient reason codes (timeouts, 5xx); configuration/auth codes require corrective action first.

Example fix

// before
catch (e) { console.log(e.message); } // 'error.message' tells little
// after
catch (e) {
  console.error(e.reasonCode, e.details.connectionId, e.details.execution);
  if (e.reasonCode === "railway_api_not_verified") await reverifyRailway(e.details.connectionId);
}
Defensive patterns

Strategy: try-catch

Type guard

const isToolGatewayError = (e) => e instanceof ToolGatewayHttpError || (typeof e.reasonCode === "string" && typeof e.status === "number");

Try / catch

try {
  return await gateway.invoke({ method: "tools/call", params });
} catch (e) {
  if (isToolGatewayError(e)) {
    switch (e.reasonCode) {
      case "railway_api_not_verified": return reverifyAndRetry(e);
      case "vercel_connect_unavailable": return configureVercelConnectAndRetry(e);
      case "request_timeout": return retryWithBackoff(e);
      default: throw e;
    }
  }
  throw e;
}

Prevention

When it happens

Trigger: Any ToolGatewayHttpError thrown deeper in the remote MCP tools/call flow — e.g. mcp_*_not_found, railway_api_not_verified, vercel_connect_unavailable, request timeouts, auth failures — reaches this catch block and is rethrown with execution metadata attached.

Common situations: Debugging a failed tool execution and inspecting the enriched details (connectionId, catalogEntryId, execution trace); duplicate wrapping is prevented by reusing the original execution when already present.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/f764b3e2a7db3af6. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/tool-gateway.ts:6124

          : null;
      const result = normalizeMcpToolResult(
        payloadRecord.result,
        "mcp_http",
        false,
        sourceTemplateKey,
      );
      await markRemoteConnectionHealth(
        connection,
        "ok",
        "Remote MCP server responded to tools/call.",
      );
      return { result, headerSummary, execution };
    } catch (error) {
      if (error instanceof RailwayError) {
        throw new ToolGatewayHttpError(error.status, error.message, error.code, { connectionId: connection.id, catalogEntryId: entry.id, execution });
      }
      if (error instanceof ToolGatewayHttpError) {
        throw new ToolGatewayHttpError(
          error.status,
          error.message,
          error.reasonCode,
          {
            ...error.details,
            execution: error.details.execution ?? execution,
          },
        );
      }
      if (error instanceof Error && error.name === "AbortError") {
        await markRemoteConnectionHealth(
          connection,
          "error",
          "Remote MCP tool call timed out.",
        );
        throw new ToolGatewayHttpError(
          504,
          "Remote MCP tool call timed out",

View on GitHub (pinned to 3f1d897a7c)