{"record":{"id":"2c946e690a3907a4","repo":"upstash/context7","slug":"invalid-context7-base-url-raw","errorCode":null,"errorMessage":"Invalid Context7 base URL: ${raw}","messagePattern":"Invalid Context7 base URL: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/setup/deployment.ts","lineNumber":18,"sourceCode":"import type { AuthOptions } from \"./agents.js\";\nimport { DEFAULT_CONTEXT7_BASE_URL } from \"../utils/api.js\";\n\nconst HOSTED_MCP_BASE_URL = \"https://mcp.context7.com\";\n\nexport type SetupDeployment =\n  | { kind: \"hosted\"; baseUrl: typeof DEFAULT_CONTEXT7_BASE_URL }\n  | { kind: \"custom\"; baseUrl: string };\nexport type CustomSetupDeployment = Extract<SetupDeployment, { kind: \"custom\" }>;\n\nexport function normalizeDeploymentBaseUrl(input?: string): string {\n  const raw = input?.trim() || DEFAULT_CONTEXT7_BASE_URL;\n  let url: URL;\n\n  try {\n    url = new URL(raw);\n  } catch {\n    throw new Error(`Invalid Context7 base URL: ${raw}`);\n  }\n\n  if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n    throw new Error(\"Context7 base URL must use http:// or https://\");\n  }\n  if (url.username || url.password) {\n    throw new Error(\"Context7 base URL must not contain credentials\");\n  }\n  if (url.search || url.hash) {\n    throw new Error(\"Context7 base URL must not contain a query string or fragment\");\n  }\n\n  url.pathname = url.pathname.replace(/\\/+$/, \"\") || \"/\";\n  const normalized = url.toString().replace(/\\/$/, \"\");\n  if (url.pathname.endsWith(\"/mcp\") || url.pathname.endsWith(\"/api\")) {\n    throw new Error(\"Pass the Context7 deployment root, without /mcp or /api\");\n  }\n  return normalized;","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/upstash/context7/blob/4416fb855b8f752be735e34f943b5d0762701aad/packages/cli/src/setup/deployment.ts#L1-L36","documentation":"Thrown by normalizeDeploymentBaseUrl when the provided deployment URL string cannot be parsed by the URL constructor. The CLI requires a syntactically valid absolute URL for a custom (on-prem) Context7 deployment; anything unparseable is rejected before any network call is made.","triggerScenarios":"resolveSetupDeployment(input) / normalizeDeploymentBaseUrl is called with a string that `new URL(raw)` cannot parse — e.g. missing scheme ('myserver.com'), whitespace-only is fine but 'http://foo bar' or ':::' fail.","commonSituations":"Typing the deployment address without the http(s):// scheme; pasting a URL with stray characters or internal spaces; shell interpolation producing an empty/garbled value in a setup flag or env var.","solutions":["Prefix the value with https:// (e.g. 'myserver.com' -> 'https://myserver.com').","Re-check the string for typos, spaces, or unexpanded shell variables.","Omit the argument entirely to fall back to DEFAULT_CONTEXT7_BASE_URL."],"exampleFix":"// before\nctx7 setup --url my-onprem.internal\n\n// after\nctx7 setup --url https://my-onprem.internal","handlingStrategy":"validation","validationCode":"function isValidDeploymentUrl(raw?: string): boolean {\n  if (!raw?.trim()) return true; // falls back to default\n  try { new URL(raw.trim()); return true; } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const dep = resolveSetupDeployment(input);\n} catch (e) {\n  console.error(`Bad --url value: ${(e as Error).message}. Include the https:// scheme.`);\n  process.exitCode = 1;\n}","preventionTips":["Always include the https:// scheme when typing deployment URLs.","Quote URLs in shells to avoid splitting on special characters.","Echo/inspect the variable holding the URL before passing it."],"tags":["url","validation","cli","configuration"],"backgroundTag":"invalid-url-format","analyzedSha":"4416fb855b8f752be735e34f943b5d0762701aad","analyzedAt":"2026-09-16T20:28:07.148Z","contentChangedAt":"2026-09-16T20:28:07.148Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}