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

  1. Pass a non-empty, non-whitespace id string to context(), e.g. context({ id: "session-main", ... })
  2. If the id comes from an env var or config, default it: id = process.env.CONTEXT_ID || "default-context"
  3. Validate/trim the id before construction and throw a domain-specific error if blank
  4. 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

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


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)