stablyai/orca · error · Error

${label} sort order changed

Error message

${label} sort order changed

What it means

locale-collator-sort-benchmark measures Intl.Collator sort performance and asserts that a 'before' baseline sort and an 'after' (optimized/cached) sort produce identical ordering for the same input. assertSameOrder compares length and element-wise equality and throws if the optimization changed observable sort output. The error is a correctness invariant, not a perf threshold.

Source

Thrown at config/scripts/locale-collator-sort-benchmark.mjs:109

      afterSamples.push(measureRound(after, afterIterations))
      beforeSamples.push(measureRound(before, beforeIterations))
    }
  }
  const middle = Math.floor(ROUND_COUNT / 2)
  return {
    beforeMs: beforeSamples.sort((a, b) => a - b)[middle],
    afterMs: afterSamples.sort((a, b) => a - b)[middle]
  }
}

function assertSameOrder(before, after, label) {
  const expected = before()
  const actual = after()
  if (
    expected.length !== actual.length ||
    expected.some((value, index) => value !== actual[index])
  ) {
    throw new Error(`${label} sort order changed`)
  }
}

const pad = (value, width) => String(value).padStart(width)
console.log('Renderer locale sort, ms per sort (median of 5 rounds). Lower is better.')
console.log(
  `${pad('mode', 9)} ${pad('items', 7)} ${pad('per-call', 11)} ${pad('reused', 11)} ${pad('speedup', 9)}`
)

for (const count of [36, 50, 250]) {
  const issues = makeJiraIssues(count)
  const before = () =>
    [...issues]
      .sort((a, b) => a.key.localeCompare(b.key, undefined, { numeric: true }))
      .map((issue) => issue.key)
  const after = () => sortJiraIssues(issues, 'key', 'asc').map((issue) => issue.key)
  assertSameOrder(before, after, `numeric ${count}`)
  const { beforeMs, afterMs } = measurePair(before, after)

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Diff the before() and after() collator construction — options and locale tag must match exactly.
  2. Reproduce by logging the first index where expected[i] !== actual[i] and inspect the two issue keys.
  3. If the optimization genuinely reorders, do not ship it; keep the original comparator and find a different speedup.
  4. Pin the locale-data/Node version if a runtime update shifted default collation behavior.

Example fix

// before
const reused = new Intl.Collator('ko')  // missing numeric option
const after = () => issues.slice().sort((a,b) => reused.compare(a.key, b.key))

// after
const reused = new Intl.Collator('ko', { numeric: true, sensitivity: 'base' })
const after = () => issues.slice().sort((a,b) => reused.compare(a.key, b.key))
Defensive patterns

Strategy: try-catch

Validate before calling

function sameOrder(a, b) {
  return a.length === b.length && a.every((v, i) => v === b[i])
}
if (!sameOrder(before(), after())) {
  throw new Error(`${label} sort order changed`)
}

Type guard

const sameOrder = (a, b) => Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((v, i) => v === b[i])

Prevention

When it happens

Trigger: The 'after' collator uses different options (sensitivity, numeric, caseFirst, locale), or a cached/reused collator returns a different comparator than the freshly-constructed one, so two issues that should be adjacent diverge.

Common situations: Refining collator options to speed up sorting accidentally changes ordering (e.g. dropping numeric:true, switching sensitivity from 'base' to 'variant'), reusing a collator built for a different locale, or a locale-data update between Node versions changing defaults.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/ccc1ada2bfe794bf. Report an issue: GitHub.