JuliusBrussee/caveman · error · Error

caveman agent: subagent maxContextTokens must be a positive

Error message

caveman agent: subagent maxContextTokens must be a positive integer

What it means

Thrown by the subagent tool factory when the effective maxContextTokens value is not a safe positive integer. This bounds how much context the subagent run may accumulate before truncation/compaction; it defaults to 128_000, so the error fires only when you override it with an invalid value.

Source

Thrown at packages/agent/src/index.ts:185

  const maxInputChars = options.maxInputChars ?? 32_768;
  if (!Number.isSafeInteger(maxInputChars) || maxInputChars <= 0) {
    throw new Error("caveman agent: subagent maxInputChars must be a positive integer");
  }
  const maxCalls = options.maxCalls ?? 1;
  const maxCostUsd = options.maxCostUsd ?? 1;
  const maxContextTokens = options.maxContextTokens ?? 128_000;
  if (!Number.isSafeInteger(maxCalls) || maxCalls <= 0) {
    throw new Error("caveman agent: subagent maxCalls must be a positive integer");
  }
  if (!Number.isFinite(maxCostUsd) || maxCostUsd <= 0) {
    throw new Error("caveman agent: subagent maxCostUsd must be positive");
  }
  if (options.maxTokens !== undefined &&
      (!Number.isSafeInteger(options.maxTokens) || options.maxTokens <= 0)) {
    throw new Error("caveman agent: subagent maxTokens must be a positive integer");
  }
  if (!Number.isSafeInteger(maxContextTokens) || maxContextTokens <= 0) {
    throw new Error("caveman agent: subagent maxContextTokens must be a positive integer");
  }
  return tool({
    name: options.name,
    description: options.description,
    input: schema.object({ task: schema.string() }),
    effect: "read",
    result: "auto",
    ...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),
    runtime: {
      kind: "subagent",
      definition: options.agent,
      maxInputChars,
      maxCalls,
      maxCostUsd,
      ...(options.maxTokens === undefined ? {} : { maxTokens: options.maxTokens }),
      maxContextTokens,
    },
    async execute() {

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Pass a positive safe integer, e.g. maxContextTokens: 128_000
  2. Omit the option to keep the 128_000 default
  3. Map model specs defensively: const ctx = Number.isSafeInteger(spec.contextWindow) && spec.contextWindow > 0 ? spec.contextWindow : 128_000
  4. Strip suffixes and round before passing: Math.round(parseInt(raw, 10))

Example fix

// before
subagentTool({ agent, name: "worker", maxContextTokens: Number(spec["context-window"]) }); // "128k" -> NaN

// after
const ctx = Number.isSafeInteger(spec.contextWindow) && spec.contextWindow > 0
  ? spec.contextWindow
  : 128_000;
subagentTool({ agent, name: "worker", maxContextTokens: ctx });
Defensive patterns

Strategy: validation

Validate before calling

const ctx = Number(cfg.contextWindow);
const maxContextTokens = Number.isSafeInteger(ctx) && ctx > 0 ? ctx : 128_000;
subagentTool({ agent, name: "worker", maxContextTokens });

Type guard

const isPositiveInt = (v: unknown): v is number =>
  Number.isSafeInteger(v) && (v as number) > 0;

Prevention

When it happens

Trigger: Passing maxContextTokens: 0, a negative number, a float such as 128000.5, NaN, or a string. Also fires when computing the value from model metadata that yields undefined math (NaN).

Common situations: Sizing the context window from a model spec object whose field is missing (undefined arithmetic -> NaN), copying a provider's context length that includes a 'k' suffix ("128k"), or reusing a value tuned for a different library that allowed 0 as 'auto'.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/9cb7147ebb85e7d8. Report an issue: GitHub.