{"record":{"id":"9c107ae7cf263ecb","repo":"can1357/oh-my-pi","slug":"budget-must-be-a-non-negative-number","errorCode":null,"errorMessage":"--budget must be a non-negative number","messagePattern":"--budget must be a non-negative number","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/metaharness/src/tb/cli.ts","lineNumber":214,"sourceCode":"\t\t\t\tthrow new Error(`unknown option: ${arg}`);\n\t\t}\n\t}\n\n\tif (config.help) return config;\n\tif (config.models.length === 0) throw new Error(\"at least one --model is required\");\n\tfor (const model of config.models) {\n\t\tconst slash = model.indexOf(\"/\");\n\t\tif (slash <= 0 || slash === model.length - 1) throw new Error(`invalid model ${model}; expected provider/model`);\n\t}\n\tfor (const [flag, value] of [\n\t\t[\"--attempts\", config.attempts],\n\t\t[\"--concurrency\", config.concurrency],\n\t\t[\"--epochs\", config.epochs],\n\t] as const) {\n\t\tif (!Number.isInteger(value) || value < 1) throw new Error(`${flag} must be a positive integer`);\n\t}\n\tif (config.budget !== null && (!Number.isFinite(config.budget) || config.budget < 0)) {\n\t\tthrow new Error(\"--budget must be a non-negative number\");\n\t}\n\treturn config;\n}\n\nclass Semaphore {\n\t#available: number;\n\t#queue: Array<() => void> = [];\n\n\tconstructor(available: number) {\n\t\tthis.#available = available;\n\t}\n\n\tasync acquire(): Promise<void> {\n\t\tif (this.#available > 0) {\n\t\t\tthis.#available--;\n\t\t\treturn;\n\t\t}\n\t\tconst { promise, resolve } = Promise.withResolvers<void>();","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/metaharness/src/tb/cli.ts#L196-L232","documentation":"parseArgs validates a Terminal-Bench run configuration before any work starts. When --budget is provided it must be a finite, non-negative number; null means 'no budget'. This guard exists to fail fast at config-parse time instead of mid-run when costs are being tracked.","triggerScenarios":"Calling parseArgs (or the tb CLI) with --budget set to a negative number (e.g. --budget=-5), a non-finite value (NaN, Infinity), or a string that fails numeric parsing while budget !== null.","commonSituations":"Typo in a script passing '--budget=-1' to signal unlimited; shell variable interpolation producing an empty/garbage value; copy-pasted config with a negative cost cap.","solutions":["Pass a non-negative finite number for --budget, e.g. --budget=10","Omit --budget (or pass null) entirely to run without a cost budget","Check the shell/env variable feeding --budget for typos or empty values"],"exampleFix":"// before\nparseArgs([\"--budget\", \"-5\"])\n// after\nparseArgs([\"--budget\", \"5\"])","handlingStrategy":"validation","validationCode":"if (config.budget !== null && (!Number.isFinite(config.budget) || config.budget < 0)) throw new Error(\"--budget must be a non-negative number\");","typeGuard":"function isValidBudget(b: unknown): b is number | null {\n  return b === null || (typeof b === \"number\" && Number.isFinite(b) && b >= 0);\n}","tryCatchPattern":null,"preventionTips":["Always pass --budget as a plain non-negative number or omit it","Validate CLI numeric args at the edge with a helper before use","Beware shell variables expanding to empty/negative values"],"tags":["cli","validation","argument-parsing"],"backgroundTag":"invalid-cli-argument","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}