can1357/oh-my-pi · warning · Error
Server "${name}" was disconnected during initial connection
Error message
Server "${name}" was disconnected during initial connection What it means
During connectServers(), after a server's connection promise resolves, the manager checks whether the server was concurrently disconnected or the manager was reset (epoch changed) while connecting. If so, it detaches and disconnects the just-created connection and throws this error naming the server. This prevents registering connections for servers that were removed mid-connect (e.g. by a /mcp reload or disconnectAll).
Source
Thrown at packages/coding-agent/src/mcp/manager.ts:576
this.#handleServerNotification(name, method, params);
},
onRequest: (method, params) => {
return this.#handleServerRequest(method, params);
},
});
})().then(
async connection => {
// Store original config (without resolved tokens) to keep
// cache keys stable and avoid leaking rotating credentials.
connection.config = config;
if (sources[name]) {
connection._source = sources[name];
}
if (this.#epoch !== connectionEpoch || this.#pendingConnections.get(name) !== connectionPromise) {
this.#detachConnection(name, connection);
void disconnectServer(connection).catch(() => {});
throw new Error(`Server "${name}" was disconnected during initial connection`);
}
this.#pendingConnections.delete(name);
this.#connections.set(name, connection);
this.#serverConfigs.set(name, config);
// Wire auth refresh for HTTP-like transports so 401s trigger token refresh.
// Gate on a resolvable managed credential, not on the auth block:
// definition-only configs (url-keyed fallback) get Bearer injection
// too and need the same mid-session refresh hook.
if (
isAuthRefreshableMCPTransport(connection.transport) &&
lookupMcpOAuthCredential(this.#authStorage, config)
) {
connection.transport.onAuthError = async () => {
const refreshed = await this.#resolveAuthConfig(config, { forceRefresh: true });
if (refreshed.type === "http" || refreshed.type === "sse") {
return refreshed.headers ?? null;View on GitHub (pinned to 9690622007)
Solutions
- Retry connectServers() after the concurrent operation (reload/disconnect) completes.
- Avoid triggering /mcp reload or disconnectAll while initial connections are in flight; wait for connection to settle first.
- Don't issue overlapping connectServers() calls for the same server; await the first call.
- Treat the error as a signal the server was removed from config — verify it's still in the current config before reconnecting.
- Check logs for which concurrent operation raced the connect.
Example fix
// before void manager.connectServers(); // fire-and-forget; user reload races it // after await manager.connectServers(); // await before allowing reload UI actions enableReloadButton();
Defensive patterns
Strategy: retry
Validate before calling
// Only connect when no conflicting lifecycle operation is in flight
if (manager.isReloading() || manager.isDisconnecting(name)) {
await manager.waitForSettled(); // or defer until reload completes
}
await manager.connectServers(); Type guard
null
Try / catch
try {
await manager.connectServers();
} catch (e) {
if (e instanceof Error && /was disconnected during initial connection/.test(e.message)) {
// server removed/reloaded mid-connect; retry once after settling
await Bun.sleep(250);
return manager.connectServers();
}
throw e;
} Prevention
- Await connectServers() before enabling reload/disconnect UI actions.
- Never fire overlapping connectServers() calls for the same server.
- Treat this as a benign race in reload flows — retry after the operation settles.
- Keep initial-connect timeouts reasonable so connections don't straddle user actions.
When it happens
Trigger: Calling connectServers() while, for the same server name: disconnectServer/disconnectAll runs, the manager epoch is bumped (reload), a duplicate connect for the same name supersedes the pending promise, or #detachConnection is invoked by another path during the handshake.
Common situations: User runs /mcp reload while servers are still connecting at startup; a slow-connecting server (slow stdio spawn or remote OAuth flow) finishes after the config was reloaded; two overlapping connectServers() calls racing for the same name; manager reset during shutdown while connections still initializing.
Related errors
- MCP server not connected: ${name}
- Server "${name}" was disconnected during reconnection
- Cannot set cwd on a disposed JS runtime
- Transport not connected
- ${name}: ${message} (joined by "; ")
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/ef09c4dcef285013.
Report an issue: GitHub.