JuliusBrussee/caveman · error · Error

caveman agent: output maxTokens must be a positive integer

Error message

caveman agent: output maxTokens must be a positive integer

What it means

output() requires maxTokens to be a positive safe integer and throws when it is missing, zero, negative, fractional, or not a Number.isSafeInteger. maxTokens is mandatory (not optional) on OutputDefinition, so undefined also fails the check. This guarantees the output budget is a usable positive integer before any model call is made.

Solutions

  1. Pass a positive integer, e.g. output({ maxTokens: 1024 }).
  2. Round and floor any computed value before passing it, ensuring it is at least 1.
  3. If the value is optional in your config, supply an explicit positive default rather than relying on the API.

Example fix

// before
const out = output({ maxTokens: 0 });
// after
const out = output({ maxTokens: 2048 });
Defensive patterns

Strategy: validation

Validate before calling

function validMaxTokens(v) { return typeof v === "number" && Number.isSafeInteger(v) && v > 0; }
if (!validMaxTokens(cfg.maxTokens)) throw new Error(`maxTokens must be a positive integer, got ${cfg.maxTokens}`);

Type guard

function isPositiveInt(v: unknown): v is number { return typeof v === "number" && Number.isSafeInteger(v) && v > 0; }

Try / catch

let out;
try { out = output({ maxTokens: cfg.maxTokens }); }
catch (e) { if (String(e.message).includes("maxTokens")) out = output({ maxTokens: 2048 }); else throw e; }

Prevention

When it happens

Trigger: output({ maxTokens: 0 }), output({ maxTokens: -1 }), a fractional value like 512.5, NaN/Infinity, or calling output({}) with maxTokens omitted entirely.

Common situations: A config value of 0 used to mean 'unlimited' (the API does not accept that); a parsed string that is not a number; multiplying by a factor that yields a float.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/a265e5bb150e7ade. Report an issue: GitHub.

Appendix: source

Thrown at packages/agent/src/primitives.ts:404

    kind: "artifact",
    strategy: options.strategy ?? "page",
    maxInlineTokens,
    recovery: options.recovery ?? "exact_ccr",
  });
}

export interface OutputDefinition<TSchemaValue extends TSchema | undefined = TSchema | undefined> {
  readonly kind: "output";
  readonly maxTokens: number;
  readonly schema?: TSchemaValue;
}

export function output<T extends TSchema | undefined = undefined>(options: {
  maxTokens: number;
  schema?: T;
}): OutputDefinition<T> {
  if (!Number.isSafeInteger(options.maxTokens) || options.maxTokens <= 0) {
    throw new Error("caveman agent: output maxTokens must be a positive integer");
  }
  return Object.freeze({
    kind: "output",
    maxTokens: options.maxTokens,
    ...(options.schema === undefined ? {} : { schema: options.schema }),
  }) as OutputDefinition<T>;
}

export type QualityGrader =
  | { type: "contains"; fragments: string[] }
  | { type: "tool_called"; tools: string[] }
  | { type: "exact_match"; expected: string }
  | { type: "json_schema"; schema: TSchema };

export type EvalGuardrail =
  | { type: "latency_threshold"; p95_ms: number }
  | { type: "error_rate"; max: number };

View on GitHub (pinned to 3ee70a1026)