remix-run/remix · error · CreateHrefError
missing-hostname
Error message
missing-hostname
What it means
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.
Source
Thrown at packages/route-pattern/src/lib/href.ts:86
...args: CreateHrefArgs<source>
): string {
pattern = typeof pattern === 'string' ? RoutePattern.parse(pattern) : pattern
let patternParts = pattern._parts
let [params, options] = args
let hasOrigin =
patternParts.protocol !== null || patternParts.hostname !== null || patternParts.port !== null
let result = ''
let targetOrigin: string | undefined
if (hasOrigin) {
let protocol =
patternParts.protocol === null || patternParts.protocol === 'http(s)'
? 'https'
: patternParts.protocol
if (patternParts.hostname === null) {
throw new CreateHrefError({ type: 'missing-hostname', pattern })
}
let hostname = hrefPart(pattern, patternParts.hostname, params ?? {})
let port = patternParts.port === null ? '' : `:${patternParts.port}`
targetOrigin = `${protocol}://${hostname}${port}`
result += targetOrigin
}
let pathname = hrefPart(pattern, patternParts.pathname, params ?? {})
pathname = '/' + pathname
result += pathname
let search = hrefSearch(patternParts.search, options?.searchParams)
let searchSuffix = search === undefined ? '' : `?${search}`
result += searchSuffix
if (options?.baseURL !== undefined) {
let baseURL = new URL(options.baseURL)View on GitHub (pinned to 9696913134)
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
Example fix
// before
let pattern = parseRoutePattern('https://:8080/users/:id')
// after
let pattern = parseRoutePattern('https://example.com:8080/users/:id') Defensive patterns
Strategy: validation
Validate before calling
let pattern = parseRoutePattern(source)
if (pattern.hostname === null && (pattern.port !== null || pattern.protocol !== null)) {
// refuse before calling href
} Type guard
null
Try / catch
try { href(pattern, params) } catch (e) { if (e?.type === 'missing-hostname') { /* rebuild pattern with host */ } } Prevention
- Author patterns with full origins or none
- Unit-test href generation for every registered pattern
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- invalid-hostname-variable
- invalid-hostname-wildcard
- nameless-wildcard
- missing-params
- invalid-pathname-variable
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/a9037ab1d8658b17.
Report an issue: GitHub.