tobi/qmd · error · Error

${name} must be a positive integer

Error message

${name} must be a positive integer

What it means

Thrown by parseEmbedBatchOption when an embed batch-size option (e.g. --batch-size) is provided but is not a positive integer. Values like 0, -1, 2.5, or 'abc' are rejected.

Source

Thrown at src/cli/qmd.ts:2091

  }
  const escaped = skippedFiles.filter(f => f.code === "OUTSIDE_COLLECTION").length;
  const unreadable = skippedFiles.length - escaped;
  if (escaped) console.warn(`Skipped ${escaped} file(s) outside the collection root`);
  if (unreadable) console.warn(`Skipped ${unreadable} unreadable file(s)`);
}

function renderProgressBar(percent: number, width: number = 30): string {
  const filled = Math.round((percent / 100) * width);
  const empty = width - filled;
  const bar = "█".repeat(filled) + "░".repeat(empty);
  return bar;
}

function parseEmbedBatchOption(name: string, value: unknown): number | undefined {
  if (value === undefined) return undefined;
  const parsed = Number(value);
  if (!Number.isInteger(parsed) || parsed < 1) {
    throw new Error(`${name} must be a positive integer`);
  }
  return parsed;
}

function parseChunkStrategy(value: unknown): ChunkStrategy | undefined {
  if (value === undefined) return undefined;
  const s = String(value);
  if (s === "auto" || s === "regex") return s;
  throw new Error(`--chunk-strategy must be "auto" or "regex" (got "${s}")`);
}

// --timeout for `qmd embed`: a cap on the whole embed session, in minutes. Returns
// the value in milliseconds, or undefined to use the default. 0 disables the cap.
function parseEmbedTimeoutOption(value: unknown): number | undefined {
  if (value === undefined) return undefined;
  const minutes = Number(value);
  if (!Number.isFinite(minutes) || minutes < 0) {
    throw new Error(`--timeout must be a non-negative number of minutes (0 = no limit)`);

View on GitHub (pinned to dbfd0b4736)

Solutions

  1. Pass a whole number >= 1, e.g. `qmd embed --batch-size 32`
  2. Omit the flag entirely to use the default
  3. If 'no limit' was intended, drop the option or use --timeout 0 (which is the capped option that supports 0)

Example fix

# before
qmd embed --batch-size 0
# after
qmd embed --batch-size 32
Defensive patterns

Strategy: type-guard

Validate before calling

const n = Number(v);
if (!Number.isInteger(n) || n < 1) throw new RangeError('--batch-size must be a positive integer');

Type guard

const isPositiveInt = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v) && v >= 1;

Prevention

When it happens

Trigger: Running `qmd embed --batch-size 0`, `--batch-size 50.5`, or a non-numeric value; passing the option through a script with an unset variable defaulting to empty string.

Common situations: Shell scripts passing empty or fractional variables; copy-pasting flags from docs with placeholder values; using 0 intending 'unlimited'.

Related errors


AI-assisted analysis of tobi/qmd@dbfd0b4736 (2026-08-28). Data as JSON: /api/errors/e3f9697b991e86b6. Report an issue: GitHub.