paperclipai/paperclip · error · Error

maxParallel must be an integer from 2 through 100

Error message

maxParallel must be an integer from 2 through 100

What it means

buildProtocolEvalCatalog validates maxParallel as a safe integer between 2 and 100 inclusive before building the eval catalog. Values outside that range, non-integers, or non-numeric input are rejected. This bounds live eval concurrency to a sane, safe range.

Source

Thrown at packages/paperclip-runner/scripts/runner-protocol-eval-campaign.mjs:126

    );
  }
  return new Set(selected);
}

export async function buildProtocolEvalCatalog({
  evalsRoot,
  rosterSelection = "all",
  campaignId,
  source = {},
  maxParallel = 100,
}) {
  safeId(campaignId, "campaign ID");
  if (
    !Number.isSafeInteger(maxParallel) ||
    maxParallel < 2 ||
    maxParallel > 100
  ) {
    throw new Error("maxParallel must be an integer from 2 through 100");
  }
  const programRoot = resolve(evalsRoot, "evals/paperclip-runner");
  const rosterRoot = resolve(programRoot, "rosters");
  const requested = parseRosterSelection(rosterSelection);
  const selected = requested ?? (await maintainedRosterSelection(programRoot));
  const rosterFiles = (await readdir(rosterRoot, { withFileTypes: true }))
    .filter(
      (entry) =>
        entry.isFile() &&
        entry.name.startsWith("live-") &&
        entry.name.endsWith(".json"),
    )
    .map((entry) => entry.name)
    .sort();
  const rosters = [];
  for (const rosterFile of rosterFiles) {
    const rosterPath = resolve(rosterRoot, rosterFile);
    const roster = await loadObject(rosterPath);

View on GitHub (pinned to 01ad858492)

Solutions

  1. Pass an integer between 2 and 100, e.g. 8.
  2. Coerce the CLI value with Number() and validate before calling (Number.isSafeInteger + range check).
  3. For serial execution, check whether the script offers a dedicated serial/sequence mode instead of maxParallel: 1.

Example fix

// before
const maxParallel = args["max-parallel"]; // "1" (string)
// after
const maxParallel = Number(args["max-parallel"] ?? 8);
if (!Number.isSafeInteger(maxParallel) || maxParallel < 2 || maxParallel > 100) throw new Error("maxParallel must be an integer from 2 through 100");
Defensive patterns

Strategy: validation

Validate before calling

const maxParallel = Number(rawMaxParallel);
if (!Number.isSafeInteger(maxParallel) || maxParallel < 2 || maxParallel > 100) throw new Error("maxParallel must be an integer from 2 through 100");

Type guard

const isValidMaxParallel = (v) => Number.isSafeInteger(v) && v >= 2 && v <= 100;

Try / catch

try {
  const catalog = await buildProtocolEvalCatalog({ maxParallel });
} catch (err) {
  if (err.message.includes("maxParallel")) console.error("Pass an integer 2-100, e.g. --max-parallel 8");
  throw err;
}

Prevention

When it happens

Trigger: Calling buildProtocolEvalCatalog with maxParallel = 1, 0, negative, > 100, a float like 2.5, or undefined/NaN (e.g. from an unparsed CLI flag).

Common situations: Passing --max-parallel 1 wanting serial execution; forgetting to Number() a string CLI arg so '8' arrives as a string; typo resulting in NaN; setting a very high value hoping to speed up the run.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/0a2be8c4884e9f46. Report an issue: GitHub.