{"record":{"id":"37d9c884c51c61a0","repo":"stablyai/orca","slug":"zustand-publication-span-publicationspanms-ms-ex","errorCode":null,"errorMessage":"Zustand publication span ${publicationSpanMs}ms exceeds --sample-ms ${options.sampleMs}","messagePattern":"Zustand publication span (.+?)ms exceeds --sample-ms (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/run-idle-cpu-benchmark.mjs","lineNumber":138,"sourceCode":"  options.lineageDepth = Math.floor(options.lineageDepth)\n  options.agentsPerWorktree = Math.floor(options.agentsPerWorktree)\n  options.zustandPublications = Math.floor(options.zustandPublications)\n  options.zustandPublicationIntervalMs = Math.max(\n    1,\n    Math.floor(options.zustandPublicationIntervalMs)\n  )\n  options.syntheticVisibleSpinners = Math.max(0, Math.floor(options.syntheticVisibleSpinners))\n  options.syntheticSpinnerSteps = Math.max(1, Math.floor(options.syntheticSpinnerSteps))\n  if (!['smooth', 'steps'].includes(options.syntheticSpinnerAnimation)) {\n    throw new Error(`Invalid --synthetic-spinner-animation: ${options.syntheticSpinnerAnimation}`)\n  }\n  if (options.lineageDepth > 0 && options.worktrees < 2) {\n    throw new Error('--lineage-depth requires at least two --worktrees')\n  }\n  const publicationSpanMs =\n    Math.max(0, options.zustandPublications - 1) * options.zustandPublicationIntervalMs\n  if (publicationSpanMs > options.sampleMs) {\n    throw new Error(\n      `Zustand publication span ${publicationSpanMs}ms exceeds --sample-ms ${options.sampleMs}`\n    )\n  }\n  return options\n}\nfunction printUsage() {\n  console.log(\n    `Usage: node config/scripts/run-idle-cpu-benchmark.mjs [options]\\n\\nOptions:\\n  --warmup-ms <n>    Time to wait after app readiness before sampling (default ${DEFAULT_WARMUP_MS})\\n  --sample-ms <n>    Sampling window duration (default ${DEFAULT_SAMPLE_MS})\\n  --interval-ms <n>  Sampling cadence (default ${DEFAULT_INTERVAL_MS})\\n  --worktrees <n>    Seed repo worktree count, including primary (default ${DEFAULT_WORKTREE_COUNT})\\n  --lineage-depth <n>  Nest all worktrees under one expanded lineage, up to this depth\\n  --agents-per-worktree <n>  Seed this many visible inline agent rows per worktree\\n  --zustand-publications <n>  Publish exactly this many store updates during sampling\\n  --zustand-publication-interval-ms <n>  Publication cadence (default ${DEFAULT_ZUSTAND_PUBLICATION_INTERVAL_MS})\\n  --headful          Show the Electron window while measuring\\n  --skip-build       Reuse out/main/index.js instead of building first\\n  --output <path>    Write JSON report to this path\\n  --disable-renderer-animations  Inject measurement-only CSS that disables animations/transitions\\n  --synthetic-visible-spinners <n>  Measurement-only: add visible working spinners\\n  --synthetic-spinner-animation <smooth|steps>  Spinner animation style (default smooth)\\n  --synthetic-spinner-steps <n>  Step count for --synthetic-spinner-animation steps (default 12)\\n`\n  )\n}\nfunction run(command, args, options = {}) {\n  execFileSync(command, args, { stdio: options.stdio ?? 'pipe', encoding: 'utf8', ...options })\n}\n\nfunction buildAppIfNeeded(root, skipBuild) {\n  const mainPath = path.join(root, 'out', 'main', 'index.js')\n  if (skipBuild && existsSync(mainPath)) {\n    return mainPath","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/run-idle-cpu-benchmark.mjs#L120-L156","documentation":"Thrown by parseArgs when the computed Zustand publication span (max(0, zustandPublications-1) * zustandPublicationIntervalMs) exceeds sampleMs. The fixture cannot fit all requested store publications inside the sampling window, so the measurement would be truncated.","triggerScenarios":"High --zustand-publications combined with a large --zustand-publication-interval-ms and a short --sample-ms, e.g. 100 publications * 1000ms interval > 30000ms sample.","commonSituations":"Scaling up publications without extending the sample window, or lowering sample-ms for a quick run.","solutions":["Lower --zustand-publications or --zustand-publication-interval-ms so the span fits in --sample-ms.","Increase --sample-ms to cover the full publication span.","Compute span = (publications-1)*interval and ensure it is <= sample-ms before running."],"exampleFix":"# before\nnode config/scripts/run-idle-cpu-benchmark.mjs --zustand-publications 100 --zustand-publication-interval-ms 1000 --sample-ms 30000\n# after\nnode config/scripts/run-idle-cpu-benchmark.mjs --zustand-publications 100 --zustand-publication-interval-ms 1000 --sample-ms 120000","handlingStrategy":"validation","validationCode":"const publicationSpanMs = Math.max(0, options.zustandPublications - 1) * options.zustandPublicationIntervalMs\nif (publicationSpanMs > options.sampleMs) {\n  throw new Error(`Zustand publication span ${publicationSpanMs}ms exceeds --sample-ms ${options.sampleMs}`)\n}","typeGuard":"function publicationsFitInSample(options) {\n  const span = Math.max(0, options.zustandPublications - 1) * options.zustandPublicationIntervalMs\n  return span <= options.sampleMs\n}","tryCatchPattern":"try {\n  options = parseArgs(argv)\n} catch (err) {\n  if (/Zustand publication span/.test(err.message)) { printUsage(); process.exit(2) }\n  throw err\n}","preventionTips":["Compute derived constraints (span vs window) explicitly and include both numbers in the error.","Document the relationship between publications, interval, and sample-ms in --help."],"tags":["cli","validation","benchmark","zustand"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}