stablyai/orca · error · Error

must be a positive integer, received

Error message

${name} must be a positive integer, received ${value}

What it means

Startup guard in the markdown TOC parse benchmark. It Number.parseInt's four env vars (ORCA_TOC_BENCH_HEADINGS, _PARAS, _CHANGES, _WARMUP) with a decimal radix and rejects anything that is not an integer > 0. NaN (non-numeric or empty string), zero, and negatives all fail. The error names which var is bad and what was received.

Solutions

  1. Unset the offending var to fall back to the documented default (400/6/200/5)
  2. Set it to a positive integer literal: ORCA_TOC_BENCH_HEADINGS=400 node markdown-toc-parse-benchmark.mjs
  3. Check for trailing whitespace or quotes in the export: printf '%s' "$ORCA_TOC_BENCH_HEADINGS" | od -c
  4. If driving from a script, validate with a positive-integer regex before exporting

Example fix

# before
export ORCA_TOC_BENCH_HEADINGS=
node config/scripts/markdown-toc-parse-benchmark.mjs

# after
unset ORCA_TOC_BENCH_HEADINGS
node config/scripts/markdown-toc-parse-benchmark.mjs
Defensive patterns

Strategy: validation

Validate before calling

function positiveIntEnv(name, fallback) {
  const raw = process.env[name]
  if (raw === undefined) return fallback
  if (!/^[1-9][0-9]*$/.test(raw)) {
    throw new Error(`${name} must be a positive integer, received ${raw}`)
  }
  return Number.parseInt(raw, 10)
}

Type guard

function isPositiveInt(v) {
  return Number.isInteger(v) && v > 0
}

Prevention

When it happens

Trigger: Setting any of the four ORCA_TOC_BENCH_* env vars to a non-numeric string, empty string, '0', a negative number, or a float like '5.5' (parseInt truncates, but '5.5' still parses to 5 so only NaN/<=0 fail).

Common situations: Typo in the env var name in CI matrix config; exporting with shell quoting that leaves an empty value (ORCA_TOC_BENCH_HEADINGS=); inheriting a value from a different benchmark's var set; or setting a float expecting it to be honored.

Related errors


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

Appendix: source

Thrown at config/scripts/markdown-toc-parse-benchmark.mjs:34

import remarkGfm from 'remark-gfm'
import remarkParse from 'remark-parse'
import { unified } from 'unified'

const DOC_HEADINGS = Number.parseInt(process.env.ORCA_TOC_BENCH_HEADINGS ?? '400', 10)
const PARAGRAPHS_PER_HEADING = Number.parseInt(process.env.ORCA_TOC_BENCH_PARAS ?? '6', 10)
// Number of debounced content changes in a sustained typing burst. The editor
// debounces serialize at 300ms, so ~200 changes ≈ a minute of steady typing.
const CONTENT_CHANGES = Number.parseInt(process.env.ORCA_TOC_BENCH_CHANGES ?? '200', 10)
const WARMUP = Number.parseInt(process.env.ORCA_TOC_BENCH_WARMUP ?? '5', 10)

for (const [name, value] of [
  ['ORCA_TOC_BENCH_HEADINGS', DOC_HEADINGS],
  ['ORCA_TOC_BENCH_PARAS', PARAGRAPHS_PER_HEADING],
  ['ORCA_TOC_BENCH_CHANGES', CONTENT_CHANGES],
  ['ORCA_TOC_BENCH_WARMUP', WARMUP]
]) {
  if (!Number.isInteger(value) || value <= 0) {
    throw new Error(`${name} must be a positive integer, received ${value}`)
  }
}

// Mirror of buildMarkdownTableOfContents()'s parse + heading walk
// (src/renderer/src/components/editor/markdown-table-of-contents.ts). Kept inline
// so the benchmark exercises the real remark pipeline without bundling the TS.
function buildMarkdownTableOfContentsLike(markdown) {
  const tree = unified()
    .use(remarkParse)
    .use(remarkGfm)
    .use(remarkFrontmatter, ['yaml', 'toml'])
    .parse(markdown)
  const headings = []
  const visit = (node) => {
    if (node.type === 'heading' && typeof node.depth === 'number') {
      let title = ''
      const collect = (n) => {
        if (typeof n.value === 'string') {

View on GitHub (pinned to 1136503c6a)