different-ai/openwork · error · McpError

InternalError

InternalError

Error message

This MCP connection needs to be reconnected in OpenWork. (or) This MCP tool catalog could not be loaded. Retry the request.

What it means

The ListTools handler for a managed enterprise MCP connection wraps any failure from resolving the connection or fetching its tool catalog into an MCP InternalError. If markReconnectWhenCredentialIsGone detects the stored credential is missing/revoked, the message tells the user to reconnect; otherwise it is a transient catalog-load failure the client should retry.

Source

Thrown at apps/server/src/local-managed-mcp.ts:1268

  const stored = await withVaultRead(config, (vault) => requireConnection(vault, workspaceId, name));
  if (!stored.enabled) {
    return new Response(JSON.stringify({ error: "connection_disabled" }), {
      status: 503,
      headers: { "content-type": "application/json" },
    });
  }
  const redirectUri = localManagedMcpCallbackUrl(config);
  const server = new Server(
    { name: `openwork-local-${name}`, version: "1.0.0" },
    { capabilities: { tools: {} } },
  );
  server.setRequestHandler(ListToolsRequestSchema, async () => {
    try {
      const connection = await enterpriseConnection(config, workspaceId, name);
      return { tools: await enterpriseClient().listTools({ connection, redirectUri }) };
    } catch (error) {
      const reconnect = await markReconnectWhenCredentialIsGone(config, workspaceId, name, error, "Tool discovery failed");
      throw new McpError(
        ErrorCode.InternalError,
        reconnect
          ? "This MCP connection needs to be reconnected in OpenWork."
          : "This MCP tool catalog could not be loaded. Retry the request.",
      );
    }
  });
  server.setRequestHandler(CallToolRequestSchema, async (call) => {
    try {
      const connection = await enterpriseConnection(config, workspaceId, name);
      const args = call.params.arguments ?? {};
      return await enterpriseClient().callTool({
        connection,
        redirectUri,
        toolName: call.params.name,
        arguments: args,
      });
    } catch (error) {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Check the connection status in OpenWork and re-run its OAuth connect flow if credentials are missing or revoked.
  2. Retry tools/list — the fallback message explicitly indicates a transient failure.
  3. Verify the workspaceId/name used to connect still matches an existing enterprise connection.
  4. Inspect server logs for 'Tool discovery failed' to see the underlying error from the upstream provider.

Example fix

// before
const tools = await client.listTools() // throws InternalError, catalog gone
// after
if (await connectionNeedsReconnect(connection)) await reconnectManagedMcp(connection)
const tools = await client.listTools()
Defensive patterns

Strategy: retry

Validate before calling

const conn = await getManagedMcpConnection(workspaceId, name)
if (!conn || conn.status !== 'connected') throw new Error('connection missing or disconnected — reconnect first')

Type guard

function isConnected(conn: { status?: string } | null | undefined): conn is { status: 'connected' } {
  return conn?.status === 'connected'
}

Try / catch

try {
  tools = await client.listTools()
} catch (e) {
  if (e instanceof McpError && e.code === ErrorCode.InternalError && /reconnected in OpenWork/.test(e.message)) {
    await promptUserToReconnect(name)
  } else if (e instanceof McpError && e.code === ErrorCode.InternalError) {
    await backoffRetry(() => client.listTools(), 3)
  } else throw e
}

Prevention

When it happens

Trigger: Sending tools/list to the managed MCP server when enterpriseConnection() fails (connection not found, vault read failure, upstream provider error) or enterpriseClient().listTools() throws; credential explicitly missing/expired yields the reconnect variant.

Common situations: OAuth token for the upstream MCP provider expired or was revoked; user deleted the connection's credential; upstream provider is down or rate-limiting; connection renamed in OpenWork while a client session is open.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/4dd5805ad0180ef8. Report an issue: GitHub.