paperclipai/paperclip · error
Runner live eval selection limit must be a positive integer
Error message
Runner live eval selection limit must be a positive integer
What it means
When a RunnerLiveEvalSelection specifies a limit, selectRunnerLiveEvalSchedule requires it to be a positive safe integer. A limit that is undefined-skipped, zero, negative, fractional, or beyond Number.MAX_SAFE_INTEGER causes this throw. The limit truncates the filtered entries list, so a non-positive value is meaningless.
Source
Thrown at packages/paperclip-runner/src/eval/live-workflow-matrix.ts:280
const caseIds = new Set(selection.caseIds ?? []);
for (const id of candidateIds) {
if (!schedule.candidates.some((candidate) => candidate.id === id)) {
throw new Error(`unknown Runner live eval candidate: ${id}`);
}
}
const scheduledCaseIds = new Set(
schedule.entries.map((entry) => entry.caseId),
);
for (const id of caseIds) {
if (!scheduledCaseIds.has(id as RunnerWorkflowEvalCase["id"])) {
throw new Error(`unknown Runner live eval case: ${id}`);
}
}
if (
selection.limit !== undefined &&
(!Number.isSafeInteger(selection.limit) || selection.limit <= 0)
) {
throw new Error(
"Runner live eval selection limit must be a positive integer",
);
}
let entries = schedule.entries.filter(
(entry) =>
(candidateIds.size === 0 || candidateIds.has(entry.candidateId)) &&
(caseIds.size === 0 || caseIds.has(entry.caseId)),
);
if (selection.limit !== undefined)
entries = entries.slice(0, selection.limit);
if (entries.length === 0) {
throw new Error(
"Runner live eval selection matched no scheduled executions",
);
}
const selectedCandidateIds = new Set(
entries.map((entry) => entry.candidateId),
);View on GitHub (pinned to 01ad858492)
Solutions
- Set limit to a positive integer, e.g. limit: 5.
- Coerce and validate: Number.isSafeInteger(limit) && limit > 0 before calling, or omit limit entirely for unlimited.
- Fix dynamic-limit computation to clamp at 1: Math.max(1, computed).
- Parse config values with parseInt and reject NaN.
Example fix
// before
const limit = Number(process.env.EVAL_LIMIT); // '' -> NaN
selectRunnerLiveEvalSchedule(schedule, { limit });
// after
const raw = Number(process.env.EVAL_LIMIT);
const limit = Number.isSafeInteger(raw) && raw > 0 ? raw : undefined;
selectRunnerLiveEvalSchedule(schedule, { limit }); Defensive patterns
Strategy: validation
Validate before calling
if (selection.limit !== undefined && (!Number.isSafeInteger(selection.limit) || selection.limit <= 0)) {
throw new Error(`selection.limit must be a positive safe integer, got ${selection.limit}`);
} Type guard
function isValidLimit(limit: unknown): limit is number {
return typeof limit === 'number' && Number.isSafeInteger(limit) && limit > 0;
} Try / catch
try {
const plan = selectRunnerLiveEvalSchedule(schedule, selection);
} catch (err) {
if ((err as Error).message === 'Runner live eval selection limit must be a positive integer') {
throw new ConfigError(`bad limit '${selection.limit}'; use a positive integer or omit for unlimited`);
}
throw err;
} Prevention
- Parse CLI/config limits with parseInt and validate before use.
- Clamp dynamically computed limits with Math.max(1, Math.floor(value)).
- Never quote numeric limits in JSON config files.
- Default to omitting limit when unlimited execution is acceptable.
When it happens
Trigger: Passing selection.limit as 0, -1, 1.5, NaN, or a non-integer parsed from config/CLI input; computing the limit dynamically (e.g. remaining budget) and letting it reach zero.
Common situations: CLI flag parsing producing a string or float; arithmetic like Math.floor(remaining / cost) yielding 0; JSON config with a quoted number; copy-paste of a limit from a different unit.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- unknown Runner live eval candidate: ${id}
- unknown Runner live eval case: ${id}
- PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD must be a positive fini
- Runner live rotation requires a valid generated-at time
- Paperclip Runner currently supports Codex only with codexPer
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/939888a0f66cdf82.
Report an issue: GitHub.