mastra-ai/mastra · warning · Error
Client ${name} exists but is undefined
Error message
Client ${name} exists but is undefined What it means
Defensive Error thrown in MCPClient's connected-client lookup when the clients map reports a key as existing but the stored value is undefined. The comment notes this should basically never happen since the map is always populated with InternalMastraMCPClient instances; it exists to satisfy TypeScript narrowing and to catch map corruption.
Source
Thrown at packages/mcp/src/client/configuration.ts:1561
}
return serverConfig;
}
private async getOrCreateClient(name: string, config: MastraMCPServerDefinition): Promise<InternalMastraMCPClient> {
if (this.disconnectPromise) {
await this.disconnectPromise;
}
const exists = this.mcpClientsById.has(name);
const existingClient = this.mcpClientsById.get(name);
this.logger.debug('Checking connected client', { name, exists });
if (exists) {
// This is just to satisfy Typescript since technically you could have this.mcpClientsById.set('someKey', undefined);
// Should never reach this point basically we always create a new MastraMCPClient instance when we add to the Map.
if (!existingClient) {
throw new Error(`Client ${name} exists but is undefined`);
}
return existingClient;
}
const mcpClient = new InternalMastraMCPClient({
name,
server: config,
timeout: config.timeout ?? this.defaultTimeout,
capabilities: config.capabilities,
});
mcpClient.__setLogger(this.logger);
this.mcpClientsById.set(name, mcpClient);
return mcpClient;
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Audit any code that touches mcpClientsById directly and ensure only valid InternalMastraMCPClient instances are set.
- Call disconnect() to properly remove the entry, then reconnect to rebuild a clean state.
- Recreate the MCPClient instance if internal state is suspected to be corrupted.
- Report upstream if reproducible through public API only.
Example fix
// before
client.mcpClientsById.set('a', undefined);
// after
client.mcpClientsById.set('a', new InternalMastraMCPClient({ name: 'a', serverConfig }));
// or to remove:
client.mcpClientsById.delete('a'); Defensive patterns
Strategy: type-guard
Type guard
function isClient(c: InternalMastraMCPClient | undefined): c is InternalMastraMCPClient {
return c instanceof InternalMastraMCPClient;
} Try / catch
try {
const c = await client.getConnectedClientForServer(name);
} catch (e) {
if (e instanceof Error && e.message.includes('exists but is undefined')) {
await client.disconnect({ name });
// recreate client / retry
} else throw e;
} Prevention
- Never mutate mcpClientsById directly; use public connect/disconnect APIs.
- Use disconnect() to remove entries rather than setting undefined.
- Avoid subclassing that bypasses the client-creation path.
- Recreate the MCPClient if internal map state is suspected corrupt.
When it happens
Trigger: Practically unreachable via public API; could only occur if something external mutated the internal mcpClientsById map (e.g., setting a key to undefined directly or via debugging/serialization).
Common situations: Custom subclassing or monkey-patching of MCPClient internals; test code inserting undefined entries; concurrent disconnect logic removing values while leaving keys.
Related errors
- Missing message source for message ${message}
- MemoryThread.${methodName}() requires an agentId. Pass it vi
- Unhandled content part type: ${(exhaustiveCheck as { type: s
- ${label} must be a string.
- Attention read-all response is missing its continuation curs
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/cecdd1ac7ef0dc43.
Report an issue: GitHub.