CherryHQ/cherry-studio · error · Error
Invalid server type
Error message
Invalid server type
What it means
Thrown during transport creation when a server has a `baseUrl` set but its type (after applying typeOverride ?? server.type ?? 'sse') is neither 'streamableHttp' nor 'sse'. The URL-based transport branch only handles these two protocols; 'stdio' and 'inMemory' types with a baseUrl are contradictory and fall through to this guard.
Source
Thrown at src/main/ai/mcp/McpRuntimeService.ts:538
getServerLogger(server).debug(`StreamableHTTPClientTransport options`, {
options: redactSensitive(options)
})
return new StreamableHTTPClientTransport(new URL(server.baseUrl), options)
} else if (urlBasedType === 'sse') {
const options: SSEClientTransportOptions = {
eventSourceInit: {
fetch: async (url, init) => {
return net.fetch(typeof url === 'string' ? url : url.toString(), init)
}
},
requestInit: {
headers: prepareHeaders()
},
authProvider
}
return new SSEClientTransport(new URL(server.baseUrl), options)
} else {
throw new Error('Invalid server type')
}
} else if (server.command) {
let cmd = server.command
let effectiveCommand = server.command
// Build a local env for the transport instead of mutating `server.env`. getServerKey(server)
// serializes server.env, so mutating it here would shift the key after connect — connect-time
// logs (emitServerLog) and list-changed cache invalidations would then land under a key that
// getServerLogs / the caches (which see the un-mutated server) never query. Keep server.env
// untouched so the key stays stable everywhere; see the "deep-copy don't mutate" pattern.
const connectEnv: Record<string, string> = { ...server.env }
// Get login shell environment first - needed for command detection and server execution
// Note: getShellEnv() is memoized, so subsequent calls are fast
const loginShellEnv = await getShellEnv()
// For package servers, use resolved configuration with platform overrides and variable substitution
if (server.dxtPath) {View on GitHub (pinned to 726446b54c)
Solutions
- Set the server type to 'sse' or 'streamableHttp' when using a baseUrl
- If the server is command-based (local), remove the baseUrl and set the command field instead
- Check the MCP settings UI to ensure the type dropdown matches the connection method (URL vs command)
- If importing a server config programmatically, validate that type and baseUrl/command are consistent
Example fix
// before
const server = {
name: 'my-server',
baseUrl: 'https://mcp.example.com/sse',
type: 'stdio' // contradictory
}
// after
const server = {
name: 'my-server',
baseUrl: 'https://mcp.example.com/sse',
type: 'sse'
} Defensive patterns
Strategy: validation
Validate before calling
function validateServerTypeConsistency(server: McpServer): void {
if (server.baseUrl && server.type && !['sse', 'streamableHttp'].includes(server.type)) {
throw new Error(`Server with baseUrl must use type 'sse' or 'streamableHttp', got '${server.type}'`)
}
if (server.command && server.type && !['stdio'].includes(server.type) && !server.baseUrl) {
// command-based servers typically use stdio
}
} Type guard
function isUrlBasedServerType(type: McpServerType | undefined): boolean {
return type === 'sse' || type === 'streamableHttp'
} Try / catch
try {
await runtime.getOrCreateClient(server)
} catch (e) {
if (e instanceof Error && e.message === 'Invalid server type') {
// Fix the type field or remove baseUrl, then retry
server.type = server.baseUrl ? 'sse' : 'stdio'
}
throw e
} Prevention
- When creating or editing a server, derive the type from whether baseUrl or command is set
- Add a UI validation that prevents saving inconsistent type + baseUrl/command combinations
- Use the getTransportCandidates helper to understand valid type mappings
When it happens
Trigger: A server entity has `baseUrl` populated and `type` set to 'stdio' or 'inMemory'. The transport selection logic checks `server.baseUrl` first, then branches on `urlBasedType`; if urlBasedType isn't 'sse' or 'streamableHttp', it throws.
Common situations: Server was configured with a remote URL but type was accidentally set to 'stdio'; a migration or import set the type incorrectly; the user mixed up local (command-based) and remote (URL-based) server configurations.
Related errors
- Either baseUrl or command must be provided
- Invalid manifest: missing server.mcp_config.command
- Invalid manifest: server.mcp_config.args must be an array
- MCP server ${server.name} is disabled
- MCP tool is disabled: ${name}
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/4c43d2d6b5bf8159.
Report an issue: GitHub.