{"record":{"id":"8169ca95354fb3dd","repo":"CherryHQ/cherry-studio","slug":"either-baseurl-or-command-must-be-provided","errorCode":null,"errorMessage":"Either baseUrl or command must be provided","messagePattern":"Either baseUrl or command must be provided","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ai/mcp/McpRuntimeService.ts","lineNumber":725,"sourceCode":"              })\n            })\n            stdioTransport.stderr?.on('end', () => {\n              const remaining = stderrDecoder.decode()\n              if (remaining.trim()) {\n                getServerLogger(server).debug(`Stdio stderr (end)`, { data: remaining })\n                this.emitServerLog(server, {\n                  timestamp: Date.now(),\n                  level: 'stderr',\n                  message: remaining.trim(),\n                  source: 'stdio'\n                })\n              }\n            })\n            // StdioClientTransport does not expose stdout as a readable stream for raw logging\n            // (stdout is reserved for JSON-RPC). Avoid attaching a listener that would never fire.\n            return stdioTransport\n          } else {\n            throw new Error('Either baseUrl or command must be provided')\n          }\n        }\n\n        const handleAuth = async (\n          client: Client,\n          transport: SSEClientTransport | StreamableHTTPClientTransport,\n          typeOverride?: McpServerType\n        ) => {\n          getServerLogger(server).debug(`Starting OAuth flow`)\n          // Create an event emitter for the OAuth callback\n          const events = new EventEmitter()\n\n          // Create a callback server\n          const callbackServer = new CallBackServer({\n            port: authProvider.config.callbackPort,\n            path: authProvider.config.callbackPath || '/oauth/callback',\n            events\n          })","sourceCodeStart":707,"sourceCodeEnd":743,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/McpRuntimeService.ts#L707-L743","documentation":"Thrown as the final fallback in transport creation when a server has neither a `baseUrl` nor a `command` field. The transport logic checks in-memory servers first, then baseUrl-based (SSE/streamableHttp), then command-based (stdio). If none match, the server configuration is fundamentally incomplete.","triggerScenarios":"A server entity in the database has both `baseUrl` and `command` as undefined/empty. This can happen with a corrupted entry, an incomplete import, or a server created with neither field populated.","commonSituations":"Server was partially configured and saved; a migration created incomplete records; the UI allowed saving without requiring at least one of baseUrl or command; programmatic server creation omitted both fields.","solutions":["Edit the server configuration in MCP settings to provide either a baseUrl (for SSE/streamableHttp) or a command (for stdio)","If the server entry is corrupted, delete it and recreate with valid configuration","Add validation in the server creation/import path to require at least one of baseUrl or command","Check the database record for the server to see what fields are actually populated"],"exampleFix":"// before\nconst server = {\n  name: 'my-server',\n  // no baseUrl, no command\n}\n\n// after\nconst server = {\n  name: 'my-server',\n  command: 'npx',\n  args: ['-y', '@my/mcp-server'],\n  type: 'stdio'\n}","handlingStrategy":"validation","validationCode":"function validateServerConfig(server: Partial<McpServer>): void {\n  if (!server.baseUrl && !server.command) {\n    throw new Error('Server must have either a baseUrl (for SSE/streamableHttp) or a command (for stdio)')\n  }\n}","typeGuard":"function hasTransportConfig(server: McpServer): boolean {\n  return Boolean(server.baseUrl) || Boolean(server.command)\n}","tryCatchPattern":"try {\n  await runtime.getOrCreateClient(server)\n} catch (e) {\n  if (e instanceof Error && e.message === 'Either baseUrl or command must be provided') {\n    // Server config is incomplete — prompt user to complete setup\n    showServerConfigDialog(server)\n    return\n  }\n  throw e\n}","preventionTips":["Require at least one of baseUrl or command in the server creation form","Validate server configs on import and reject entries missing both fields","Run a data integrity check on the servers table to find incomplete records"],"tags":["mcp","transport","configuration","validation"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}