{"record":{"id":"77e80888225631a1","repo":"can1357/oh-my-pi","slug":"token-budget-must-be-a-positive-integer-when-provi","errorCode":null,"errorMessage":"token_budget must be a positive integer when provided","messagePattern":"token_budget must be a positive integer when provided","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/goals/tools/goal-tool.ts","lineNumber":53,"sourceCode":"\tconst resolvedGoal = goal ?? null;\n\treturn {\n\t\tgoal: resolvedGoal,\n\t\tremainingTokens: remainingTokens(resolvedGoal),\n\t\tcompletionBudgetReport:\n\t\t\toptions?.includeCompletionReport && resolvedGoal?.status === \"complete\"\n\t\t\t\t? completionBudgetReport(resolvedGoal)\n\t\t\t\t: null,\n\t};\n}\n\nfunction validateCreateParams(params: GoalToolInput): { objective: string; tokenBudget?: number } {\n\tconst objective = params.objective?.trim();\n\tif (!objective) {\n\t\tthrow new ToolError(\"objective is required when op=create\");\n\t}\n\tconst tokenBudget = params.token_budget;\n\tif (tokenBudget !== undefined && (!Number.isInteger(tokenBudget) || tokenBudget <= 0)) {\n\t\tthrow new ToolError(\"token_budget must be a positive integer when provided\");\n\t}\n\treturn { objective, tokenBudget };\n}\n\nexport class GoalTool implements AgentTool<typeof goalSchema, GoalToolDetails> {\n\treadonly name = \"goal\";\n\treadonly label = \"Goal\";\n\treadonly description = prompt.render(goalDescription);\n\treadonly parameters = goalSchema;\n\treadonly strict = true;\n\treadonly intent = \"omit\" as const;\n\treadonly #session: ToolSession;\n\n\tconstructor(session: ToolSession) {\n\t\tthis.#session = session;\n\t}\n\n\tasync execute(","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/goals/tools/goal-tool.ts#L35-L71","documentation":"The optional `token_budget` parameter of goal create must be a positive integer when provided. validateCreateParams rejects undefined-only absence but any provided value that is not an integer (float, 0, negative, NaN) throws this ToolError.","triggerScenarios":"Calling goal op=create with token_budget=0, a negative number, a float like 1024.5, or a non-numeric value; passing token_budget: null or a numeric string.","commonSituations":"An LLM hallucinates a budget of 0 or a decimal; callers pass user-typed CLI/config values that were never parsed to an integer; copying examples with placeholder values.","solutions":["Omit `token_budget` entirely if you don't want a budget (only validate when defined)","Round/parse the value to a positive integer before calling: Number.isInteger(v) && v > 0","Coerce numeric strings with Number() and validate before passing"],"exampleFix":"// before\nawait tool.execute({ op: \"create\", objective: \"x\", token_budget: 0 });\n// after\nawait tool.execute({ op: \"create\", objective: \"x\", token_budget: 4096 });","handlingStrategy":"validation","validationCode":"if (input.token_budget !== undefined && (!Number.isInteger(input.token_budget) || input.token_budget <= 0)) {\n  throw new Error(\"token_budget must be a positive integer\");\n}","typeGuard":"function isValidTokenBudget(v: unknown): v is number {\n  return typeof v === \"number\" && Number.isInteger(v) && v > 0;\n}","tryCatchPattern":"try {\n  await goalTool.execute({ op: \"create\", objective, token_budget });\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"token_budget\")) {\n    // drop or correct the budget and retry\n  } else throw err;\n}","preventionTips":["Omit token_budget rather than sending 0/null","Sanitize numeric input with Math.round/Number before passing","Never pass user strings directly; parse then validate"],"tags":["validation","tool-input","numeric-validation"],"backgroundTag":"invalid-parameter-value","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}