{"record":{"id":"ccc1ada2bfe794bf","repo":"stablyai/orca","slug":"label-sort-order-changed","errorCode":null,"errorMessage":"${label} sort order changed","messagePattern":"(.+?) sort order changed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/locale-collator-sort-benchmark.mjs","lineNumber":109,"sourceCode":"      afterSamples.push(measureRound(after, afterIterations))\n      beforeSamples.push(measureRound(before, beforeIterations))\n    }\n  }\n  const middle = Math.floor(ROUND_COUNT / 2)\n  return {\n    beforeMs: beforeSamples.sort((a, b) => a - b)[middle],\n    afterMs: afterSamples.sort((a, b) => a - b)[middle]\n  }\n}\n\nfunction assertSameOrder(before, after, label) {\n  const expected = before()\n  const actual = after()\n  if (\n    expected.length !== actual.length ||\n    expected.some((value, index) => value !== actual[index])\n  ) {\n    throw new Error(`${label} sort order changed`)\n  }\n}\n\nconst pad = (value, width) => String(value).padStart(width)\nconsole.log('Renderer locale sort, ms per sort (median of 5 rounds). Lower is better.')\nconsole.log(\n  `${pad('mode', 9)} ${pad('items', 7)} ${pad('per-call', 11)} ${pad('reused', 11)} ${pad('speedup', 9)}`\n)\n\nfor (const count of [36, 50, 250]) {\n  const issues = makeJiraIssues(count)\n  const before = () =>\n    [...issues]\n      .sort((a, b) => a.key.localeCompare(b.key, undefined, { numeric: true }))\n      .map((issue) => issue.key)\n  const after = () => sortJiraIssues(issues, 'key', 'asc').map((issue) => issue.key)\n  assertSameOrder(before, after, `numeric ${count}`)\n  const { beforeMs, afterMs } = measurePair(before, after)","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/locale-collator-sort-benchmark.mjs#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Diff the before() and after() collator construction — options and locale tag must match exactly.","Reproduce by logging the first index where expected[i] !== actual[i] and inspect the two issue keys.","If the optimization genuinely reorders, do not ship it; keep the original comparator and find a different speedup.","Pin the locale-data/Node version if a runtime update shifted default collation behavior."],"exampleFix":"// before\nconst reused = new Intl.Collator('ko')  // missing numeric option\nconst after = () => issues.slice().sort((a,b) => reused.compare(a.key, b.key))\n\n// after\nconst reused = new Intl.Collator('ko', { numeric: true, sensitivity: 'base' })\nconst after = () => issues.slice().sort((a,b) => reused.compare(a.key, b.key))","handlingStrategy":"try-catch","validationCode":"function sameOrder(a, b) {\n  return a.length === b.length && a.every((v, i) => v === b[i])\n}\nif (!sameOrder(before(), after())) {\n  throw new Error(`${label} sort order changed`)\n}","typeGuard":"const sameOrder = (a, b) => Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((v, i) => v === b[i])","tryCatchPattern":null,"preventionTips":["Keep before/after collator locale and options byte-for-byte identical.","Log the first divergent index and the two keys when order differs.","Pin Node/locale-data version if a runtime update shifts default collation."],"tags":["benchmark","assertion","collator","locale","correctness"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}