{"record":{"id":"b6b01703c1fb2be8","repo":"JuliusBrussee/caveman","slug":"caveman-agent-artifact-maxinlinetokens-must-be-a","errorCode":null,"errorMessage":"caveman agent: artifact maxInlineTokens must be a non-negative integer","messagePattern":"caveman agent: artifact maxInlineTokens must be a non-negative integer","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/agent/src/primitives.ts","lineNumber":383,"sourceCode":"  };\n  return Object.freeze(definition);\n}\n\nexport interface ArtifactDefinition {\n  readonly kind: \"artifact\";\n  readonly strategy: \"verbatim\" | \"json-index\" | \"page\";\n  readonly maxInlineTokens: number;\n  readonly recovery: \"exact_ccr\" | \"source_ref\";\n}\n\nexport function artifact(options: {\n  strategy?: ArtifactDefinition[\"strategy\"];\n  maxInlineTokens?: number;\n  recovery?: ArtifactDefinition[\"recovery\"];\n} = {}): ArtifactDefinition {\n  const maxInlineTokens = options.maxInlineTokens ?? 1_200;\n  if (!Number.isSafeInteger(maxInlineTokens) || maxInlineTokens < 0) {\n    throw new Error(\"caveman agent: artifact maxInlineTokens must be a non-negative integer\");\n  }\n  return Object.freeze({\n    kind: \"artifact\",\n    strategy: options.strategy ?? \"page\",\n    maxInlineTokens,\n    recovery: options.recovery ?? \"exact_ccr\",\n  });\n}\n\nexport interface OutputDefinition<TSchemaValue extends TSchema | undefined = TSchema | undefined> {\n  readonly kind: \"output\";\n  readonly maxTokens: number;\n  readonly schema?: TSchemaValue;\n}\n\nexport function output<T extends TSchema | undefined = undefined>(options: {\n  maxTokens: number;\n  schema?: T;","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/primitives.ts#L365-L401","documentation":"artifact() defaults maxInlineTokens to 1200 but validates any explicitly provided value must be a non-negative safe integer. It throws when maxInlineTokens is negative, fractional, NaN, Infinity, or otherwise not a Number.isSafeInteger. The value controls how many tokens of the artifact may be inlined, so only 0 and positive integers are meaningful.","triggerScenarios":"Calling artifact({ maxInlineTokens: -5 }) or any negative number; a float such as 100.5; NaN or Infinity; a non-number coerced incorrectly. The default (omitted) value of 1200 never triggers it.","commonSituations":"Subtracting tokens from a budget and going below zero; passing a computed average or ratio that is fractional; passing a string or null from parsed config.","solutions":["Pass a non-negative safe integer (>= 0), or omit maxInlineTokens to use the default 1200.","Clamp the computed value: Math.max(0, Math.floor(value)).","Validate before the call: Number.isSafeInteger(v) && v >= 0."],"exampleFix":"// before\nconst art = artifact({ id: \"report\", maxInlineTokens: -100 });\n// after\nconst art = artifact({ id: \"report\", maxInlineTokens: Math.max(0, computedTokens) });","handlingStrategy":"validation","validationCode":"function validMaxInlineTokens(v) { return v === undefined || (Number.isSafeInteger(v) && v >= 0); }\nif (!validMaxInlineTokens(opts.maxInlineTokens)) throw new Error(`maxInlineTokens must be a non-negative integer, got ${opts.maxInlineTokens}`);","typeGuard":"function isNonNegativeInt(v: unknown): v is number { return typeof v === \"number\" && Number.isSafeInteger(v) && v >= 0; }","tryCatchPattern":"let art;\ntry { art = artifact({ id, maxInlineTokens }); }\ncatch (e) { if (String(e.message).includes(\"maxInlineTokens\")) art = artifact({ id }); else throw e; }","preventionTips":["Clamp computed budgets: Math.max(0, Math.floor(value)).","Don't pass token math results directly; round to integers first.","Rely on the default 1200 unless you have a concrete budget reason."],"tags":["validation","typescript","artifact","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}