remix-run/remix · error · Error

Cannot compare matches for different URLs: ${a.url.href} vs

Error message

Cannot compare matches for different URLs: ${a.url.href} vs ${b.url.href}

What it means

The specificity compare() function throws when asked to compare two Match objects that were produced against different URLs. Specificity comparison is only meaningful for matches on the same URL because it compares which pattern matches that URL more specifically.

Source

Thrown at packages/route-pattern/src/lib/specificity.ts:66

 * Comparator function for sorting matches from most specific to least specific.
 *
 * @param a the first match to compare
 * @param b the second match to compare
 * @returns positive if `a` is less specific, negative if more specific, 0 if equal
 */
export const descending = (a: Match, b: Match): number => compare(a, b) * -1

/**
 * Compare two matches by specificity.
 * Passing to `.sort()` will sort matches from least specific to most specific.
 *
 * @param a the first match to compare
 * @param b the second match to compare
 * @returns -1 if `a` is less specific, 1 if `a` is more specific, 0 if tied.
 */
export function compare(a: Match, b: Match): -1 | 0 | 1 {
  if (a.url.href !== b.url.href) {
    throw new Error(`Cannot compare matches for different URLs: ${a.url.href} vs ${b.url.href}`)
  }
  let aParts = a.pattern._parts
  let bParts = b.pattern._parts

  let protocolResult = compareProtocol(aParts.protocol, bParts.protocol)
  if (protocolResult !== 0) return protocolResult

  let portResult = comparePort(aParts.port, bParts.port)
  if (portResult !== 0) return portResult

  let hostname = decodeHostname(a.url.hostname)

  let hostnameResult = compareHostname(hostname, a.paramsMeta.hostname, b.paramsMeta.hostname)
  if (hostnameResult !== 0) return hostnameResult

  let pathnameResult = comparePathname(a.paramsMeta.pathname, b.paramsMeta.pathname)
  if (pathnameResult !== 0) return pathnameResult

View on GitHub (pinned to 9696913134)

Solutions

  1. Only compare matches produced from the same URL
  2. Re-match the patterns against a single URL before comparing
  3. Group matches by URL before sorting

Example fix

// before
compare(matchA, matchB) // different URLs
// after
let matches = patterns.map((p) => p.match(url)).filter((m) => m !== null)
sort(ascending)(matches)
Defensive patterns

Strategy: validation

Validate before calling

function sameUrl(a: Match, b: Match): boolean {
  return a.url.href === b.url.href
}

Prevention

When it happens

Trigger: Calling compare(a, b) (or helpers like lessThan, greaterThan, equal, assertCompare, or sorting with ascending/descending) where a.url.href !== b.url.href, e.g. matches from two different requests or two different test URLs.

Common situations: Sorting an array of matches collected across multiple requests; mixing matches from tests fixtures with different URLs; caching matches and comparing stale ones against new ones.

Related errors


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