JuliusBrussee/caveman · error · Error
caveman agent: context ttlTurns must be a positive integer
Error message
caveman agent: context ttlTurns must be a positive integer
What it means
Thrown by the context() builder when the optional ttlTurns is present but is not a safe integer greater than zero. ttlTurns bounds how many conversation turns a context segment stays alive, so 0, negatives, fractions, and non-numbers are invalid; omitting the field entirely means no turn-based expiry.
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 27d5a3981a)
Solutions
- Pass a positive integer (e.g. ttlTurns: 10) or omit ttlTurns when the segment should live for the whole run
- Round computed values: ttlTurns: Math.max(1, Math.ceil(derived))
- Coerce config values with Number() and validate Number.isSafeInteger before calling context()
Example fix
// before
context({ id: 'scratch', kind: 'episodic', source: note, stability: 'volatile', ttlTurns: totalTurns / 4 });
// after
context({ id: 'scratch', kind: 'episodic', source: note, stability: 'volatile', ttlTurns: Math.max(1, Math.ceil(totalTurns / 4)) }); Defensive patterns
Strategy: validation
Validate before calling
function toTtlTurns(raw: unknown): number | undefined {
if (raw === undefined) return undefined;
const n = typeof raw === 'number' ? raw : Number(raw);
if (!Number.isSafeInteger(n) || n <= 0) throw new Error(`ttlTurns must be a positive integer, got ${String(raw)}`);
return n;
} Type guard
function isTtlTurns(value: unknown): value is number { return typeof value === 'number' && Number.isSafeInteger(value) && value > 0; } Prevention
- Omit ttlTurns for whole-run segments instead of using 0
- Round ratio-derived turn counts with Math.ceil
- Keep ttlTurns as an integer field in config schemas
When it happens
Trigger: Calling context({ ttlTurns: 0 }), ttlTurns: -3, ttlTurns: 2.5, ttlTurns: NaN, or ttlTurns beyond 2^53-1.
Common situations: Computing ttlTurns from a ratio (totalTurns / 4) and passing the fraction; using 0 to mean 'no limit' (the correct no-limit is to omit the option); config strings not coerced to numbers.
Related errors
- cave_compaction_option_invalid
- caveman agent: memory recallBudget must be a non-negative in
- caveman agent: context id is required
- caveman agent: artifact maxInlineTokens must be a non-negati
- caveman agent: output maxTokens must be a positive integer
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/8301edad241dfd05.
Report an issue: GitHub.