{"record":{"id":"bbd9cdb6fe02b8fe","repo":"paperclipai/paperclip","slug":"paperclip-eval-max-campaign-cost-usd-must-be-a-pos","errorCode":null,"errorMessage":"PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD must be a positive finite number","messagePattern":"PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD must be a positive finite number","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/eval/live-workflow-matrix.ts","lineNumber":20,"sourceCode":"\nimport type {\n  RunnerWorkflowEvalCase,\n  RunnerWorkflowObservation,\n  RunnerWorkflowProvider,\n} from \"./workflow-contracts.js\";\nimport { RUNNER_WORKFLOW_CATALOG } from \"./workflow-catalog.js\";\n\nexport const RUNNER_LIVE_CANDIDATE_SCHEMA =\n  \"paperclip.runner.live-eval-candidate.v1\" as const;\nexport const RUNNER_LIVE_SCHEDULE_SCHEMA =\n  \"paperclip.runner.live-eval-schedule.v1\" as const;\n\nexport function parseRunnerLiveCampaignCostLimit(\n  value: string | undefined,\n): number {\n  const parsed = Number(value ?? \"12\");\n  if (!Number.isFinite(parsed) || parsed <= 0) {\n    throw new Error(\n      \"PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD must be a positive finite number\",\n    );\n  }\n  return parsed;\n}\n\nexport function runnerLiveRotationWeek(generatedAt: string): number {\n  const epochMs = Date.parse(generatedAt);\n  if (!Number.isFinite(epochMs)) {\n    throw new Error(\"Runner live rotation requires a valid generated-at time\");\n  }\n  const epochWeek = Math.floor(epochMs / (7 * 86_400_000));\n  return ((epochWeek % 7) + 7) % 7;\n}\n\nexport type RunnerLiveAdapter =\n  \"codex_app_server\" | \"opencode_server\" | \"acpx_runtime\";\nexport type RunnerLiveTier = \"strong\" | \"inexpensive\";","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/eval/live-workflow-matrix.ts#L2-L38","documentation":"parseRunnerLiveCampaignCostLimit parses the PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD environment variable into the campaign's maximum spend in USD. When set, the value must parse via Number() as a finite number greater than 0; anything else (empty string, non-numeric text, 0, negative, Infinity) throws. Unset defaults to 12.","triggerScenarios":"PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD is set to a non-numeric string ('twelve', '12 USD', ''), to 0, to a negative value, or to a value that Number() maps to NaN/Infinity ('1e400'). Note an empty string parses as 0, which fails the >0 check.","commonSituations":"Typo or stray characters in the env var in CI secrets; quoting issues leaving literal quotes in the value; setting it to '0' intending 'unlimited' (zero is rejected); locale-formatted numbers with commas ('1,50'); exporting it empty in a shell profile.","solutions":["Unset the variable entirely to use the built-in default of 12 USD.","Set a plain positive finite decimal, e.g. PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD=25 (no currency symbols, commas, or units).","Check for empty-string export in shell profiles/CI; an empty value becomes 0 and fails — use `unset PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD` instead.","Verify in CI that the secret/variable interpolates to just the number without quotes or whitespace."],"exampleFix":"// before\nexport PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD=\"\"\n// after\nunset PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD  # or: export PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD=25","handlingStrategy":"validation","validationCode":"export function isValidCostLimit(v: string | undefined): boolean {\n  if (v === undefined) return true; // default 12 applies\n  const n = Number(v);\n  return Number.isFinite(n) && n > 0;\n}\n// usage: if (!isValidCostLimit(process.env.PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD)) throw ...","typeGuard":null,"tryCatchPattern":"try {\n  const limit = parseRunnerLiveCampaignCostLimit(process.env.PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD);\n} catch {\n  console.error(\"PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD must be a plain positive finite number, e.g. 25; unset for default 12\");\n  process.exit(2);\n}","preventionTips":["Only set the variable to a plain decimal number: no currency symbols, commas, units, or quotes.","To get 'unlimited-ish' behavior raise the number; do not use 0 (rejected) — unset the variable for the default 12.","In CI, echo the variable before the run to catch empty or mis-interpolated secret values.","Validate env vars at pipeline start with a fail-fast preflight step."],"tags":["configuration","env-var","validation","eval"],"backgroundTag":"invalid-env-var-value","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-02T18:44:00.616Z","contentChangedAt":"2026-09-02T18:44:00.616Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}