{"record":{"id":"7d3be12f48b8674c","repo":"NousResearch/hermes-agent","slug":"url-required","errorCode":null,"errorMessage":"URL required","messagePattern":"URL required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"web/src/lib/mcp-server-create.ts","lineNumber":56,"sourceCode":"  for (const rawLine of raw.split(\"\\n\")) {\n    const line = rawLine.trim();\n    if (!line) continue;\n    const separator = line.indexOf(\"=\");\n    if (separator === -1) continue;\n    const key = line.slice(0, separator).trim();\n    const value = line.slice(separator + 1).trim();\n    if (key) env[key] = value;\n  }\n  return env;\n}\n\nexport function buildMcpServerCreate(draft: McpServerDraft): McpServerCreate {\n  const name = draft.name.trim();\n  if (!name) throw new Error(\"Name required\");\n\n  if (draft.transport === \"http\") {\n    const url = draft.url.trim();\n    if (!url) throw new Error(\"URL required\");\n    if (draft.httpAuth === \"header\" && !draft.bearerToken.trim()) {\n      throw new Error(\"Bearer token required\");\n    }\n\n    const server: McpServerCreate = { name, url };\n    if (draft.httpAuth !== \"none\") server.auth = draft.httpAuth;\n    if (draft.httpAuth === \"header\") {\n      server.bearer_token = draft.bearerToken;\n    }\n    return server;\n  }\n\n  const command = draft.command.trim();\n  if (!command) throw new Error(\"Command required\");\n\n  const server: McpServerCreate = { name, command };\n  const args = parseArgs(draft.args);\n  if (args.length) server.args = args;","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/web/src/lib/mcp-server-create.ts#L38-L74","documentation":"For an MCP server with transport 'http', buildMcpServerCreate requires a non-empty URL (trimmed) — it becomes the `url` field of the McpServerCreate payload. Thrown client-side before the API call when the URL field is blank on the HTTP transport branch.","triggerScenarios":"Selecting the HTTP/SSE transport in the add-server form but leaving the URL field empty; a draft defaulting transport to 'http' with url: ''; whitespace-only input.","commonSituations":"Form state initialized with transport 'http' while the user fills in command/args fields instead (intending stdio); UI not resetting fields when the transport toggles.","solutions":["Enter the server's HTTP endpoint (e.g. https://mcp.example.com/sse) and resubmit.","If you meant a local process, switch the transport to stdio/command instead of http.","Gate the submit action on url.trim() when transport === 'http'."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const requiredFields = draft.transport === 'http' ? ['url'] : ['command']\nconst missing = requiredFields.filter(f => !String(draft[f] ?? '').trim())\nif (missing.length) { setFieldErrors(missing); return }","typeGuard":"function hasHttpUrl(d: McpServerDraft): boolean {\n  return d.transport === 'http' && d.url.trim().length > 0\n}","tryCatchPattern":"try {\n  const payload = buildMcpServerCreate(draft)\n} catch (err) {\n  if (String(err) === 'URL required') { focusField('url'); return }\n  throw err\n}","preventionTips":["Clear/show fields per transport so users can't leave the wrong branch's required field blank.","Show inline hints listing required fields for the selected transport.","Consider URL-format validation (new URL(...)) beyond mere presence."],"tags":["validation","mcp","http-transport","form"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}