{"record":{"id":"34ad719f94032c51","repo":"JuliusBrussee/caveman","slug":"caveman-agent-subagent-maxtokens-must-be-a-positi","errorCode":null,"errorMessage":"caveman agent: subagent maxTokens must be a positive integer","messagePattern":"caveman agent: subagent maxTokens must be a positive integer","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/agent/src/index.ts","lineNumber":182,"sourceCode":"  maxTokens?: number;\n  maxContextTokens?: number;\n}): ToolDefinition {\n  const maxInputChars = options.maxInputChars ?? 32_768;\n  if (!Number.isSafeInteger(maxInputChars) || maxInputChars <= 0) {\n    throw new Error(\"caveman agent: subagent maxInputChars must be a positive integer\");\n  }\n  const maxCalls = options.maxCalls ?? 1;\n  const maxCostUsd = options.maxCostUsd ?? 1;\n  const maxContextTokens = options.maxContextTokens ?? 128_000;\n  if (!Number.isSafeInteger(maxCalls) || maxCalls <= 0) {\n    throw new Error(\"caveman agent: subagent maxCalls must be a positive integer\");\n  }\n  if (!Number.isFinite(maxCostUsd) || maxCostUsd <= 0) {\n    throw new Error(\"caveman agent: subagent maxCostUsd must be positive\");\n  }\n  if (options.maxTokens !== undefined &&\n      (!Number.isSafeInteger(options.maxTokens) || options.maxTokens <= 0)) {\n    throw new Error(\"caveman agent: subagent maxTokens must be a positive integer\");\n  }\n  if (!Number.isSafeInteger(maxContextTokens) || maxContextTokens <= 0) {\n    throw new Error(\"caveman agent: subagent maxContextTokens must be a positive integer\");\n  }\n  return tool({\n    name: options.name,\n    description: options.description,\n    input: schema.object({ task: schema.string() }),\n    effect: \"read\",\n    result: \"auto\",\n    ...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),\n    runtime: {\n      kind: \"subagent\",\n      definition: options.agent,\n      maxInputChars,\n      maxCalls,\n      maxCostUsd,\n      ...(options.maxTokens === undefined ? {} : { maxTokens: options.maxTokens }),","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/index.ts#L164-L200","documentation":"Thrown by the subagent tool factory when options.maxTokens is present but not a safe positive integer. maxTokens optionally caps the subagent model's output tokens; because it is optional, passing undefined skips the check, but any supplied value must be a whole number >= 1 (NaN, 0, negatives, floats, and numeric strings all throw).","triggerScenarios":"Explicitly passing maxTokens: 0, maxTokens: -1, maxTokens: 4096.5, maxTokens: NaN, or maxTokens: \"4096\". Unlike maxCalls/maxContextTokens there is no default — the error only fires when the option is defined and invalid.","commonSituations":"Forwarding a model-config object where maxTokens is optional and sometimes null/0, converting a provider's token limit (some providers accept -1 for 'default', this library does not), or typo'ing a numeric string.","solutions":["Pass a positive safe integer, e.g. maxTokens: 8192","If you do not need an output cap, omit the option entirely (undefined is accepted)","Normalize optional config: maxTokens: cfg.maxTokens ?? undefined after checking it is a safe integer > 0","Clamp floats: Math.max(1, Math.round(cfg.maxTokens))"],"exampleFix":"// before\nsubagentTool({ agent, name: \"worker\", maxTokens: cfg.max_tokens ?? 0 });\n\n// after\nsubagentTool({\n  agent,\n  name: \"worker\",\n  ...(Number.isSafeInteger(cfg.max_tokens) && cfg.max_tokens > 0\n    ? { maxTokens: cfg.max_tokens }\n    : {}),\n});","handlingStrategy":"validation","validationCode":"if (cfg.maxTokens !== undefined &&\n    (!Number.isSafeInteger(cfg.maxTokens) || cfg.maxTokens <= 0)) {\n  throw new Error(`maxTokens must be a positive integer when provided, got ${cfg.maxTokens}`);\n}\nsubagentTool({ agent, name: \"worker\", ...(cfg.maxTokens === undefined ? {} : { maxTokens: cfg.maxTokens }) });","typeGuard":"const isOptionalPositiveInt = (v: unknown): v is number | undefined =>\n  v === undefined || (Number.isSafeInteger(v) && v > 0);","tryCatchPattern":null,"preventionTips":["Keep maxTokens optional in your own config types so absent means omitted, not 0","Map provider sentinels (-1 for default) to undefined before passing through","Round any computed token budget: Math.max(1, Math.round(v))"],"tags":["subagent","validation","token-limits","configuration"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}