{"record":{"id":"33057fa42afb8dcb","repo":"different-ai/openwork","slug":"mcp-shutdown-failed","errorCode":"MCP_SHUTDOWN_FAILED","errorMessage":"Enterprise MCP failed during ${phaseLabel[input.operationPhase]}${request}.","messagePattern":"Enterprise MCP failed during (.+?)(.+?)\\.","errorType":"exception","errorClass":"EnterpriseMcpClientError","httpStatus":null,"severity":"warning","filePath":"packages/enterprise-mcp-client/src/enterprise-mcp-client.ts","lineNumber":426,"sourceCode":"      operation: async (session) => {\n        try {\n          await connectWithProtocolNegotiation({\n            session,\n            connectionId: input.connection.id,\n            operationPhase: input.operationPhase,\n          })\n          let operationFailed = false\n          try {\n            return await input.operation(session)\n          } catch (error) {\n            operationFailed = true\n            throw error\n          } finally {\n            try {\n              await closeWithinDeadline(() => session.client.close(), closeTimeoutMs)\n            } catch (error) {\n              if (!operationFailed) {\n                throw new EnterpriseMcpClientError({\n                  operationPhase: \"shutdown\",\n                  requestPhase: session.observer.lastRequestPhase(),\n                  cause: error,\n                })\n              }\n            }\n          }\n        } catch (error) {\n          await invalidateTerminallyRejectedCredential(session, {\n            connectionId: input.connection.id,\n            operationPhase: input.operationPhase,\n          })\n          throw error\n        }\n      },\n    })\n  }\n","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/enterprise-mcp-client/src/enterprise-mcp-client.ts#L408-L444","documentation":"runConnectedOperation in packages/enterprise-mcp-client/src/enterprise-mcp-client.ts throws an EnterpriseMcpClientError with operationPhase \"shutdown\" and code MCP_SHUTDOWN_FAILED when closing the MCP session (session.client.close()) fails or exceeds closeTimeoutMs AND the operation itself did not already fail. The work may have succeeded; only teardown failed. Note the guard: if operationFailed is true, the shutdown error is swallowed so the original operation error propagates instead.","triggerScenarios":"listTools, callTool, listResources, readResource, or listResourceTemplates completes, but the finally-block close times out past closeTimeoutMs (default 5000ms) or the underlying transport's close() rejects (socket already destroyed, server hung up mid-close).","commonSituations":"Slow or half-dead server connections where the HTTP transport close hangs; very small configured closeTimeoutMs; network interruption right after a successful call; server that closes abruptly after responding.","solutions":["Increase closeTimeoutMs in createEnterpriseMcpClient options if closes are merely slow.","Treat this as teardown-only: check whether the operation result was already obtained; retry the operation if its result is unknown.","Inspect error.cause to distinguish a timeout (\"did not close before its deadline\") from a transport close rejection.","Check server-side connection handling/timeouts; a server that kills sockets during close triggers this."],"exampleFix":"// before\ncreateEnterpriseMcpClient({ closeTimeoutMs: 500 })\n\n// after\ncreateEnterpriseMcpClient({ closeTimeoutMs: 10_000 })","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  result = await client.listTools(input)\n} catch (error) {\n  if (error instanceof EnterpriseMcpClientError && error.operationPhase === \"shutdown\") {\n    // operation result unknown/lost to teardown: log cause, optionally retry\n    console.warn(\"MCP session close failed:\", error.cause)\n  } else throw error\n}","preventionTips":["Set a realistic closeTimeoutMs (default 5s) for slow or remote servers","Monitor for repeated shutdown errors — they usually indicate server-side connection handling problems","Don't assume the operation failed: shutdown errors occur only when the operation itself did not throw"],"tags":["shutdown","timeout","session-lifecycle","network"],"backgroundTag":"session-close-timeout","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}