{"record":{"id":"a9037ab1d8658b17","repo":"remix-run/remix","slug":"missing-hostname","errorCode":null,"errorMessage":"missing-hostname","messagePattern":"missing-hostname","errorType":"validation","errorClass":"CreateHrefError","httpStatus":null,"severity":"error","filePath":"packages/route-pattern/src/lib/href.ts","lineNumber":86,"sourceCode":"  ...args: CreateHrefArgs<source>\n): string {\n  pattern = typeof pattern === 'string' ? RoutePattern.parse(pattern) : pattern\n  let patternParts = pattern._parts\n  let [params, options] = args\n\n  let hasOrigin =\n    patternParts.protocol !== null || patternParts.hostname !== null || patternParts.port !== null\n  let result = ''\n  let targetOrigin: string | undefined\n\n  if (hasOrigin) {\n    let protocol =\n      patternParts.protocol === null || patternParts.protocol === 'http(s)'\n        ? 'https'\n        : patternParts.protocol\n\n    if (patternParts.hostname === null) {\n      throw new CreateHrefError({ type: 'missing-hostname', pattern })\n    }\n    let hostname = hrefPart(pattern, patternParts.hostname, params ?? {})\n\n    let port = patternParts.port === null ? '' : `:${patternParts.port}`\n    targetOrigin = `${protocol}://${hostname}${port}`\n    result += targetOrigin\n  }\n\n  let pathname = hrefPart(pattern, patternParts.pathname, params ?? {})\n  pathname = '/' + pathname\n  result += pathname\n\n  let search = hrefSearch(patternParts.search, options?.searchParams)\n  let searchSuffix = search === undefined ? '' : `?${search}`\n  result += searchSuffix\n\n  if (options?.baseURL !== undefined) {\n    let baseURL = new URL(options.baseURL)","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/route-pattern/src/lib/href.ts#L68-L104","documentation":"When generating an href from a route pattern, the pattern includes an origin component (port or protocol requiring a host) but the pattern itself has no hostname segment, so there is nothing to fill the hostname from. createHref refuses to build a URL like `https://:8080/...` with an empty host.","triggerScenarios":"Calling href/createHref with a pattern that has a port or non-wildcard protocol but no hostname span (e.g. a pattern like `https://:8080/users` or one where the hostname is null), or a pattern string that parsed to hostname: null while other origin parts exist.","commonSituations":"Constructing pattern strings by concatenation and forgetting the host; refactoring patterns from pathname-only to full-URL and leaving an incomplete literal; using a constant port without a host placeholder.","solutions":["Add a hostname to the pattern: `https://example.com:8080/users/:id`","Or use a wildcard/splat hostname if any host should match: `https://\\*:8080/...`","Or drop the port/protocol so the pattern is pathname-only","Write a test that builds hrefs for every registered pattern to catch malformed ones early"],"exampleFix":"// before\nlet pattern = parseRoutePattern('https://:8080/users/:id')\n\n// after\nlet pattern = parseRoutePattern('https://example.com:8080/users/:id')","handlingStrategy":"validation","validationCode":"let pattern = parseRoutePattern(source)\nif (pattern.hostname === null && (pattern.port !== null || pattern.protocol !== null)) {\n  // refuse before calling href\n}","typeGuard":"null","tryCatchPattern":"try { href(pattern, params) } catch (e) { if (e?.type === 'missing-hostname') { /* rebuild pattern with host */ } }","preventionTips":["Author patterns with full origins or none","Unit-test href generation for every registered pattern"],"tags":["route-pattern","href","url"],"backgroundTag":"invalid-url-pattern","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}