JuliusBrussee/caveman · error
caveman agent: context ttlTurns must be a positive integer
Error message
caveman agent: context ttlTurns must be a positive integer
What it means
context() validates that ttlTurns, when provided, is a positive safe integer (Number.isSafeInteger and > 0). The library throws this error at definition time to reject context definitions with an invalid time-to-live, such as zero, negative, fractional, or non-integer values. It is a synchronous constructor-style validation so misuse fails immediately rather than silently misbehaving at runtime.
Solutions
- Pass a positive integer for ttlTurns (>= 1), or omit the property entirely if the context should not expire.
- Validate/round the value before calling context(): Number.isSafeInteger(v) && v > 0.
- If ttlTurns comes from config, coerce and check it: Math.floor(Number(raw)) and reject non-finite values.
Example fix
// before
const ctx = context({ id: "history", ttlTurns: 0 });
// after
const ctx = context({ id: "history", ttlTurns: 10 }); // or omit ttlTurns Defensive patterns
Strategy: validation
Validate before calling
function validTtlTurns(v) { return v === undefined || (Number.isSafeInteger(v) && v > 0); }
if (!validTtlTurns(opts.ttlTurns)) throw new Error(`ttlTurns must be a positive integer, got ${opts.ttlTurns}`); Type guard
function isPositiveInt(v: unknown): v is number { return typeof v === "number" && Number.isSafeInteger(v) && v > 0; } Try / catch
let ctx;
try { ctx = context({ id: "history", ttlTurns }); }
catch (e) { if (String(e.message).includes("ttlTurns")) ctx = context({ id: "history" }); else throw e; } Prevention
- Omit ttlTurns rather than passing 0 for 'no expiry'.
- Coerce config values with Math.floor(Number(raw)) and validate before constructing contexts.
- Centralize context creation in a helper that validates options once.
When it happens
Trigger: Calling context({ id, ttlTurns }) where ttlTurns is 0, negative (e.g. -1), a float (e.g. 2.5), NaN, Infinity, or otherwise not a Number.isSafeInteger. Any other option value does not trigger this error.
Common situations: Computing ttlTurns from config math that yields a float or negative number; passing a string parsed value without coercion; using a default placeholder of 0 intending 'no expiry' instead of omitting ttlTurns.
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
- caveman agent: artifact maxInlineTokens must be a…
- caveman agent: context id is required
- caveman agent: output maxTokens must be a positive integer
- artifactId is required
- assemble requires model and sessionId
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/8301edad241dfd05.
Report an issue: GitHub.
Appendix: source
Thrown at packages/agent/src/primitives.ts:350
readonly ttlTurns?: number;
}
export function context(options: {
id: string;
kind: ContextKind;
source: string | FileSource;
stability: ContextStability;
safety?: SafetyClass;
priority?: ContextPriority;
recovery?: RecoveryKind;
cacheRegion?: CacheRegion;
privacy?: PrivacyClass;
opaque?: boolean;
ttlTurns?: number;
}): ContextDefinition {
if (options.id.trim() === "") throw new Error("caveman agent: context id is required");
if (options.ttlTurns !== undefined && (!Number.isSafeInteger(options.ttlTurns) || options.ttlTurns <= 0)) {
throw new Error("caveman agent: context ttlTurns must be a positive integer");
}
const definition: ContextDefinition = {
kind: "context",
id: options.id,
segmentKind: options.kind,
source: options.source,
stability: options.stability,
safety: options.safety ?? "S0",
priority: options.priority ?? "required",
recovery: options.recovery ?? "none",
cacheRegion: options.cacheRegion ?? (options.stability === "build" ? "frozen_prefix" : "live_zone"),
privacy: options.privacy ?? "local_sensitive",
opaque: options.opaque ?? false,
...(options.ttlTurns === undefined ? {} : { ttlTurns: options.ttlTurns }),
};
return Object.freeze(definition);
}
View on GitHub (pinned to 3ee70a1026)