remix-run/remix · error · CreateHrefError

invalid-hostname-wildcard

Error message

invalid-hostname-wildcard

What it means

A value substituted for a hostname wildcard (`*`) in a pattern contained a character that is structurally invalid in a hostname (@ : / ? # %). Unlike a variable param, dots are fine for wildcards (they span multiple labels), but these reserved characters still break the URL.

Source

Thrown at packages/route-pattern/src/lib/href.ts:393

export function validateHostnameVariable(value: unknown): string {
  let serialized = String(value)
  for (let char of serialized) {
    if (char === '.' || isInvalidHostnameParamChar(char)) {
      throw new CreateHrefError({
        type: 'invalid-hostname-variable',
        value: serialized,
        char,
      })
    }
  }
  return serialized
}

export function validateHostnameWildcard(value: unknown): string {
  let serialized = String(value)
  for (let char of serialized) {
    if (isInvalidHostnameParamChar(char)) {
      throw new CreateHrefError({
        type: 'invalid-hostname-wildcard',
        value: serialized,
        char,
      })
    }
  }
  return serialized
}

function isInvalidHostnameParamChar(char: string): boolean {
  let code = char.charCodeAt(0)
  return code <= 0x1f || code === 0x7f || HOSTNAME_PARAM_STRUCTURAL_CHARS.includes(char)
}

View on GitHub (pinned to 9696913134)

Solutions

  1. Pass only the hostname portion (scheme, path, query stripped)
  2. Include the port in the pattern (`https://*:8080`) rather than in the wildcard value
  3. Sanitize values to reject @ : / ? # % before building hrefs

Example fix

// before
href(pattern, { '*': 'example.com:8080' })

// after
href(parseRoutePattern('https://*:8080/x'), { '*': 'example.com' })
Defensive patterns

Strategy: validation

Validate before calling

function isCleanHostname(v: string) { return ![...v].some(c => '@:/?#%'.includes(c)) }

Type guard

function isHostnameWildcardValue(value: unknown): value is string {
  return typeof value === 'string' && value.length > 0 && ![...value].some(c => '@:/?#%'.includes(c))
}

Prevention

When it happens

Trigger: Calling href on a pattern like `https://*/path` with params { '*': 'host/path' } or any value containing @, :, /, ?, #, or %.

Common situations: Passing full URLs or URIs into a hostname wildcard param; interpolating user input with query strings or ports; port values mistakenly folded into the host string (the `:` is invalid).

Related errors


AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27). Data as JSON: /api/errors/2096b4cb2bc51b63. Report an issue: GitHub.