{"record":{"id":"939888a0f66cdf82","repo":"paperclipai/paperclip","slug":"runner-live-eval-selection-limit-must-be-a-positiv","errorCode":null,"errorMessage":"Runner live eval selection limit must be a positive integer","messagePattern":"Runner live eval selection limit must be a positive integer","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/eval/live-workflow-matrix.ts","lineNumber":280,"sourceCode":"  const caseIds = new Set(selection.caseIds ?? []);\n  for (const id of candidateIds) {\n    if (!schedule.candidates.some((candidate) => candidate.id === id)) {\n      throw new Error(`unknown Runner live eval candidate: ${id}`);\n    }\n  }\n  const scheduledCaseIds = new Set(\n    schedule.entries.map((entry) => entry.caseId),\n  );\n  for (const id of caseIds) {\n    if (!scheduledCaseIds.has(id as RunnerWorkflowEvalCase[\"id\"])) {\n      throw new Error(`unknown Runner live eval case: ${id}`);\n    }\n  }\n  if (\n    selection.limit !== undefined &&\n    (!Number.isSafeInteger(selection.limit) || selection.limit <= 0)\n  ) {\n    throw new Error(\n      \"Runner live eval selection limit must be a positive integer\",\n    );\n  }\n  let entries = schedule.entries.filter(\n    (entry) =>\n      (candidateIds.size === 0 || candidateIds.has(entry.candidateId)) &&\n      (caseIds.size === 0 || caseIds.has(entry.caseId)),\n  );\n  if (selection.limit !== undefined)\n    entries = entries.slice(0, selection.limit);\n  if (entries.length === 0) {\n    throw new Error(\n      \"Runner live eval selection matched no scheduled executions\",\n    );\n  }\n  const selectedCandidateIds = new Set(\n    entries.map((entry) => entry.candidateId),\n  );","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/eval/live-workflow-matrix.ts#L262-L298","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst limit = Number(process.env.EVAL_LIMIT); // '' -> NaN\nselectRunnerLiveEvalSchedule(schedule, { limit });\n// after\nconst raw = Number(process.env.EVAL_LIMIT);\nconst limit = Number.isSafeInteger(raw) && raw > 0 ? raw : undefined;\nselectRunnerLiveEvalSchedule(schedule, { limit });","handlingStrategy":"validation","validationCode":"if (selection.limit !== undefined && (!Number.isSafeInteger(selection.limit) || selection.limit <= 0)) {\n  throw new Error(`selection.limit must be a positive safe integer, got ${selection.limit}`);\n}","typeGuard":"function isValidLimit(limit: unknown): limit is number {\n  return typeof limit === 'number' && Number.isSafeInteger(limit) && limit > 0;\n}","tryCatchPattern":"try {\n  const plan = selectRunnerLiveEvalSchedule(schedule, selection);\n} catch (err) {\n  if ((err as Error).message === 'Runner live eval selection limit must be a positive integer') {\n    throw new ConfigError(`bad limit '${selection.limit}'; use a positive integer or omit for unlimited`);\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["validation","configuration","eval","runner"],"backgroundTag":"invalid-argument-value","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}