stablyai/orca · error
normalizer mismatch at ${kb} KB
Error message
normalizer mismatch at ${kb} KB What it means
Thrown by the agent-hook-normalizer benchmark as a correctness guard: at each payload size (4/16/64/256 KB) it runs the production-modeled round-trip validator (serialize -> scan -> parse -> normalizeObject) and the direct validator (normalizeObject directly), then JSON.stringifies both results. If they differ, the benchmark's mirrored direct path has drifted from the round-trip path and the timing comparison is meaningless.
Source
Thrown at config/scripts/agent-hook-normalizer-roundtrip-benchmark.mjs:185
const samples = []
for (let round = 0; round < 5; round += 1) {
const start = performance.now()
for (let index = 0; index < ITERATIONS; index += 1) {
fn(payload)
}
samples.push((performance.now() - start) / ITERATIONS)
}
samples.sort((a, b) => a - b)
return samples[2]
}
const rows = []
for (const kb of [4, 16, 64, 256]) {
const payload = makePayload(kb * 1024)
const before = validateViaRoundTrip(payload)
const after = validateDirect(payload)
if (JSON.stringify(before) !== JSON.stringify(after)) {
throw new Error(`normalizer mismatch at ${kb} KB`)
}
rows.push({
label: `${kb} KB`,
beforeUs: measure(validateViaRoundTrip, payload) * 1000,
afterUs: measure(validateDirect, payload) * 1000
})
}
const pad = (value, width) => String(value).padStart(width)
console.log('Agent-status payload validation, per hook event')
console.log(
`field cap=${ASSISTANT_MESSAGE_CAP} iterations=${ITERATIONS} warmup=${WARMUP} (median of 5 rounds)`
)
console.log(
`${pad('payload', 9)} ${pad('round trip', 12)} ${pad('direct', 10)} ${pad('speedup', 9)}`
)
for (const row of rows) {
console.log(View on GitHub (pinned to 1136503c6a)
Solutions
- Diff normalizeObject/normalizeField in the benchmark against the production normalizer in agent-hook-listener.ts and re-align them.
- Confirm ASSISTANT_MESSAGE_CAP is read from the same source both arms use (it is — readMirroredConstant reads agent-status-types.ts).
- Re-run after each edit to normalizeObject until all four payload sizes match.
- If the mismatch is intentional (you are demonstrating a behavior change), update the comparison expectation rather than removing the guard.
Example fix
// before — benchmark's normalizeObject dropped the toolInput field
// -> 'normalizer mismatch at 4 KB'
// after — restore the field so both arms agree
// function normalizeObject(payload) {
// return {
// state: payload.state,
// prompt: normalizeField(payload.prompt, ASSISTANT_MESSAGE_CAP),
// agentType: payload.agentType,
// toolName: normalizeField(payload.toolName, ASSISTANT_MESSAGE_CAP),
// toolInput: normalizeField(payload.toolInput, ASSISTANT_MESSAGE_CAP),
// lastAssistantMessage: normalizeField(payload.lastAssistantMessage, ASSISTANT_MESSAGE_CAP)
// }
// } Defensive patterns
Strategy: validation
Validate before calling
function assertBothArmsAgree(payload) {
const before = validateViaRoundTrip(payload)
const after = validateDirect(payload)
if (JSON.stringify(before) !== JSON.stringify(after)) {
throw new Error('Normalizer arms disagree — direct path drifted from round trip')
}
}
// run for each payload size before the timing loop Prevention
- When editing normalizeObject/normalizeField in the benchmark, re-run all four payload sizes immediately to catch divergence.
- Keep the benchmark's normalizeObject field list identical to the production normalizer's field list.
- Re-read ASSISTANT_MESSAGE_CAP from the source constant every run (already done) so a cap change cannot silently desync the arms.
When it happens
Trigger: normalizeObject or normalizeField in the benchmark was edited and no longer matches what the round trip produces; the ASSISTANT_MESSAGE_CAP read from agent-status-types.ts changed and now the two paths clamp differently; the field list in normalizeObject drifted from the production normalizer.
Common situations: Refactor of the benchmark's normalizeObject that added/removed a field; AGENT_STATUS_ASSISTANT_MESSAGE_MAX_LENGTH changed upstream and the benchmark re-read it but the round-trip arm still uses a stale value somewhere; newline-run handling in normalizeField diverged from production.
Related errors
- agent-status-types.ts no longer defines ${name}; re-sync thi
- ${name} must be a positive integer, received ${value}
- resolved values differ for ${baseRef}:\n serial ${JSON.
- advertised-url-watcher.ts no longer contains \`${marker}\`
- ${name} must be a positive integer, received ${value}
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/40397422ce40fd3c.
Report an issue: GitHub.