remix-run/remix · error · CreateHrefError

missing-params

Error message

missing-params

What it means

After serializing a pattern part, one or more named params were referenced by the pattern but missing from the supplied params object (and were not optional). The error carries the list of missing param names so callers know exactly what to supply.

Source

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

        ) {
          i += 1
        }
        continue
      }
      // oxfmt-ignore
      stack[stack.length - 1].href +=
        part.type === 'pathname' && token.type === ':' ? encodePathnameVariableParam(pattern, token.name, value) :
        part.type === 'pathname' && token.type === '*' ? encodePathnameWildcard(value) :
        part.type === 'hostname' && token.type === ':' ? validateHostnameVariable(value) :
        part.type === 'hostname' && token.type === '*' ? validateHostnameWildcard(value) :
        unreachable()
      i += 1
      continue
    }
    unreachable(token.type)
  }
  if (missingParams.length > 0) {
    throw new CreateHrefError({
      type: 'missing-params',
      pattern,
      missingParams,
      params,
    })
  }
  if (stack.length !== 1) unreachable()
  return stack[0].href
}

function hrefSearch(
  constraints: RoutePatternParts['search'],
  searchParams?: CreateHrefSearchParams,
): string | undefined {
  let urlSearchParams =
    searchParams instanceof URLSearchParams
      ? new URLSearchParams(searchParams)
      : new URLSearchParams()

View on GitHub (pinned to 9696913134)

Solutions

  1. Supply every required param listed in error.missingParams
  2. Make genuinely optional segments optional in the pattern with parentheses: `/users/:id(/edit)`
  3. Derive params from a typed source (e.g. route param types) so missing keys are compile-time errors
  4. Log the pattern alongside params at build time in dev to catch bad link generation

Example fix

// before
href(userPostPattern, { id: '1' }) // postId missing

// after
href(userPostPattern, { id: '1', postId: '42' })
Defensive patterns

Strategy: validation

Validate before calling

let required = pattern.pathname.tokens.filter(t => t.type === ':').map(t => t.name)
let missing = required.filter(n => params[n] == null)
if (missing.length) throw new Error(`Missing params: ${missing.join(', ')}`)

Type guard

function hasAllParams(pattern: RoutePattern, params: Record<string, unknown>): boolean {
  return collectParamNames(pattern).every(name => params[name] != null)
}

Try / catch

try { href(pattern, params) } catch (e) { if (e?.type === 'missing-params' && e.missingParams) { /* fill or skip */ } }

Prevention

When it happens

Trigger: Calling href/createHref on a pattern like `/users/:id/posts/:postId` with params missing `postId` (or all params). Only thrown after the whole part is processed, once all gaps are collected.

Common situations: Building links programmatically from partial objects; type mismatches (string vs number keys); patterns updated to require new params while call sites weren't; typos in param names (postId vs postID).

Related errors


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