{"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/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/primitives.ts#L365-L401","documentation":"Thrown by the artifact() builder when maxInlineTokens is not a safe non-negative integer. maxInlineTokens caps how many tokens of an artifact may be inlined into model-visible context; the default when omitted is 1,200. Negative values, fractions, NaN, and non-numbers are rejected because the cap feeds deterministic token budgeting.","triggerScenarios":"Calling artifact({ maxInlineTokens: -1 }), 0.5, NaN, Infinity, a numeric string '1200', or a value above 2^53-1. Note 0 is legal (artifact never inlined).","commonSituations":"Scaling the cap from a model context size (window * 0.1) and passing the raw fraction; reading the number from env/config as a string; using -1 as an 'unlimited' sentinel from other APIs.","solutions":["Pass a non-negative integer or omit maxInlineTokens to accept the 1,200 default","Round computed caps: maxInlineTokens: Math.max(0, Math.trunc(window * 0.1))","There is no 'unlimited' — pick the largest inline budget your context window actually affords"],"exampleFix":"// before\nartifact({ strategy: 'page', maxInlineTokens: contextWindow * 0.05 });\n\n// after\nartifact({ strategy: 'page', maxInlineTokens: Math.max(0, Math.trunc(contextWindow * 0.05)) });","handlingStrategy":"validation","validationCode":"function toMaxInlineTokens(raw: unknown): number | undefined {\n  if (raw === undefined) return undefined;\n  const n = typeof raw === 'number' ? raw : Number(raw);\n  if (!Number.isSafeInteger(n) || n < 0) throw new Error(`maxInlineTokens must be a non-negative integer, got ${String(raw)}`);\n  return n;\n}","typeGuard":"function isMaxInlineTokens(value: unknown): value is number { return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0; }","tryCatchPattern":null,"preventionTips":["Accept the 1,200 default unless measurement says otherwise","Math.trunc every computed token budget","Remember 0 means 'never inline', not 'unlimited'"],"tags":["validation","artifact","numeric","tokens"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}