JuliusBrussee/caveman · error
caveman agent: context id is required
Error message
caveman agent: context id is required
What it means
The context() primitive requires a non-blank options.id, which names the context definition. An id that is empty or consists only of whitespace (the check trims before comparing) is rejected. Context ids must identify the definition, so an empty id would produce an unusable, unaddressable context.
Solutions
- Pass a non-empty, non-whitespace id string to context(), e.g. context({ id: "session-main", ... })
- If the id comes from an env var or config, default it: id = process.env.CONTEXT_ID || "default-context"
- Validate/trim the id before construction and throw a domain-specific error if blank
- Fix upstream string construction (joins, trims, slicing) that can produce an empty id
Example fix
// before
const id = process.env.CONTEXT_ID ?? ""; // unset -> ""
context({ id, ttlTurns: 10 });
// after
const id = process.env.CONTEXT_ID?.trim() || "default-context";
context({ id, ttlTurns: 10 }); Defensive patterns
Strategy: validation
Validate before calling
function isValidContextId(id) {
return typeof id === "string" && id.trim() !== "";
}
// before calling: if (!isValidContextId(id)) throw new Error(`bad context id: ${JSON.stringify(id)}`); Type guard
function isNonEmptyString(v: unknown): v is string {
return typeof v === "string" && v.trim() !== "";
} Try / catch
try {
const def = context({ id, ttlTurns });
} catch (err) {
if (err instanceof Error && err.message.includes("context id is required")) {
console.error(`Invalid context id ${JSON.stringify(id)}: provide a non-blank string`);
return;
}
throw err;
} Prevention
- Default env/config-derived ids: id = rawId?.trim() || "default-context"
- Validate ids at config-load time, not at construction time only
- Type context options with a branded non-empty string type where practical
- Add a unit test asserting context({ id: "" }) and context({ id: " " }) both throw
When it happens
Trigger: Calling context() with id: "" or id: " ", or with an id computed from an empty variable (e.g. process.env.CONTEXT_ID unset yields ""), or with a template/prompt-derived id that trimmed down to nothing.
Common situations: An env var or config field feeding the id is missing or blank; a dynamic id built by joining/trimming other fields ends up empty; forgetting to pass id entirely in loosely-typed call sites.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- cave_mastra_max_steps_invalid
- caveman agent: context ttlTurns must be a positive integer
- caveman agent: memory recallBudget must be a non-negative…
- invalid_deadline
- maxLoadedTools must be a positive integer
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/4d09f97b8808e1bd.
Report an issue: GitHub.
Appendix: source
Thrown at packages/agent/src/primitives.ts:348
readonly privacy: PrivacyClass;
readonly opaque: boolean;
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)