stablyai/orca · error · Error
projection mismatch at ${agents} agents
Error message
projection mismatch at ${agents} agents What it means
Correctness assertion in the projection benchmark: the cached projection builder (makeCachedBuilder) must produce byte-identical output to buildFull for the same agent map. A mismatch means the incremental cache has a correctness bug — measuring its speed would be measuring wrong output. Fires on the cold call (no prior ping) for agent counts 3/8/20/40.
Source
Thrown at config/scripts/mobile-agent-status-projection-benchmark.mjs:176
for (let index = 0; index < ITERATIONS; index += 1) {
current = ping(current, index)
build(current)
}
samples.push((performance.now() - start) / ITERATIONS)
}
samples.sort((a, b) => a - b)
return samples[2]
}
const pad = (value, width) => String(value).padStart(width)
console.log('Mobile agent-status projection, per status ping (one agent changed)')
console.log(`bucket=${BUCKET_MS}ms iterations=${ITERATIONS} warmup=${WARMUP} (median of 5 rounds)`)
console.log(`${pad('agents', 8)} ${pad('full', 11)} ${pad('cached', 11)} ${pad('speedup', 9)}`)
for (const agents of [3, 8, 20, 40]) {
const map = makeMap(agents)
const cachedBuilder = makeCachedBuilder()
if (buildFull(map) !== cachedBuilder(map)) {
throw new Error(`projection mismatch at ${agents} agents`)
}
// Why also after a ping: the cold call reuses nothing, so a stale-row bug would
// only surface once the cache is actually exercised.
const pinged = ping(map, 0)
if (buildFull(pinged) !== cachedBuilder(pinged)) {
throw new Error(`projection mismatch after a ping at ${agents} agents`)
}
const full = measure(buildFull, map)
const cached = measure(makeCachedBuilder(), map)
console.log(
`${pad(agents, 8)} ${pad(`${full.toFixed(4)} ms`, 11)} ${pad(`${cached.toFixed(4)} ms`, 11)} ${pad(`${(full / cached).toFixed(1)}x`, 9)}`
)
}
console.log(
'\nThis runs on the global store subscriber, so the cost is paid per status ping\nand scales with the number of agents running in parallel — the workload this\napp exists for.'
)
View on GitHub (pinned to 1136503c6a)
Solutions
- Diff the two output strings character-by-character to localize the divergence
- Audit makeCachedBuilder's cache key against every field buildFull reads
- Ensure makeCachedBuilder is called fresh inside the agents loop (no cross-iteration cache leakage)
- Add a focused unit test on the cached builder for the failing agent count
Defensive patterns
Strategy: validation
Validate before calling
function assertProjectionMatches(builder, cached, map, agents) {
if (builder(map) !== cached(map)) {
throw new Error(`cached projection diverges at ${agents} agents (cold) — do not trust timings`)
}
} Prevention
- Always run the equality assertion before measuring; never disable it to get numbers
- Keep makeCachedBuilder inside the agents loop so no cross-iteration cache leaks
- Add a focused unit test for the cached builder at each agent count
When it happens
Trigger: cachedBuilder(map) returns a different string than buildFull(map) for a freshly-constructed map of N agents, before any ping.
Common situations: Refactoring makeCachedBuilder and forgetting a cache key; changing the projection format in buildFull without updating the cached variant; a stale cache surviving between iterations because makeCachedBuilder is hoisted out of the loop.
Related errors
- projection mismatch after a ping at ${agents} agents
- resolved values differ for ${baseRef}:\n serial ${JSON.
- ${label} sort order changed
- 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/a31d2437dd48c34e.
Report an issue: GitHub.