{"record":{"id":"62c208106103deeb","repo":"sipeed/picoclaw","slug":"mcp-server-server-name-requires-a-url","errorCode":null,"errorMessage":"MCP server ${server.name} requires a URL.","messagePattern":"MCP server (.+?) requires a URL\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"web/frontend/src/components/config/config-page.tsx","lineNumber":469,"sourceCode":"\n          const baselineServersByName = new Map(\n            baseline.mcpServers\n              .map((server) => ({\n                ...server,\n                name: server.name.trim(),\n              }))\n              .filter((server) => server.name !== \"\")\n              .map((server) => [server.name, server] as const),\n          )\n\n          const upsertServerEntries = normalizedServers.map((server) => {\n            const deferredPatch = { deferred: server.deferredOverride }\n            const baselineServer = baselineServersByName.get(server.name)\n            const shouldValidateServer = server.enabled\n\n            if (server.type !== \"stdio\") {\n              if (shouldValidateServer && server.url === \"\") {\n                throw new Error(`MCP server ${server.name} requires a URL.`)\n              }\n\n              if (shouldValidateServer) {\n                try {\n                  const parsedURL = new URL(server.url)\n                  if (\n                    parsedURL.protocol !== \"http:\" &&\n                    parsedURL.protocol !== \"https:\"\n                  ) {\n                    throw new Error(\"invalid protocol\")\n                  }\n                } catch {\n                  throw new Error(\n                    `MCP server ${server.name} requires a valid HTTP(S) URL.`,\n                  )\n                }\n              }\n","sourceCodeStart":451,"sourceCodeEnd":487,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/web/frontend/src/components/config/config-page.tsx#L451-L487","documentation":"Validation error thrown in handleSave (web/frontend/src/components/config/config-page.tsx:469) while building the MCP servers patch: a server of type other than 'stdio' (i.e. an HTTP/SSE remote server) that is enabled has an empty URL after trimming. Disabled (enabled=false) servers skip this check via shouldValidateServer, so only active remote servers must have a URL.","triggerScenarios":"Adding an enabled remote MCP server, filling in its name but leaving the URL field empty, then saving; also when a saved remote server's URL was cleared in the UI.","commonSituations":"User fills name first intending to paste the URL later and forgets; URL field contains only spaces; user thinks command applies to remote servers too.","solutions":["Enter the server's HTTP(S) endpoint URL, e.g. https://mcp.example.com/sse","If the server is not ready yet, toggle it to disabled — disabled remote servers are exempt from URL validation","If the server is actually a local process, switch its type to 'stdio' and fill the command instead"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const needsURL = (s: McpServerForm) => s.type !== \"stdio\" && s.enabled\nif (form.mcpServers.some((s) => needsURL(s) && s.url.trim() === \"\")) {\n  setFieldError(\"Enabled remote MCP servers require a URL.\")\n  return\n}","typeGuard":null,"tryCatchPattern":"try {\n  await handleSave()\n} catch (err) {\n  if (err instanceof Error) setError(err.message) // message names the server\n}","preventionTips":["Mark the URL field required (visually) for enabled remote server rows","Disable validation-exempt state by reminding users disabled servers are not started","Trim the URL on blur so whitespace-only values are visibly empty"],"tags":["validation","frontend","mcp","url","config"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}