JuliusBrussee/caveman · error

assemble requires model and sessionId

Error message

assemble requires model and sessionId

What it means

cave.assemble() validates its options before building a cache-optimal request from the given slots. Both `model` and `sessionId` are required because the assembly hash ledger is keyed per session and the emitted cache hints are model-specific. The SDK throws this Error locally when either field is empty/undefined, before any hashing or network work happens.

Solutions

  1. Pass a non-empty `model` string (e.g. "claude-sonnet-4") and a non-empty `sessionId` in the AssembleOptions object.
  2. If the model is dynamic, validate the config/env value before calling assemble and substitute a default.
  3. Generate a sessionId explicitly (crypto.randomUUID()) if your workflow has no natural session id.
  4. In TypeScript, let the AssembleOptions type catch the omission at compile time instead of casting partial objects with `as`.

Example fix

// before
cave.assemble({ provider: "anthropic", slots });

// after
cave.assemble({
  provider: "anthropic",
  model: "claude-sonnet-4",
  sessionId: process.env.SESSION_ID ?? crypto.randomUUID(),
  slots
});
Defensive patterns

Strategy: validation

Validate before calling

function validateAssembleOptions(opts) {
  if (!opts.model) throw new Error("assemble: model is required");
  if (!opts.sessionId) throw new Error("assemble: sessionId is required");
}

Type guard

function canAssemble(opts) {
  return typeof opts.model === "string" && opts.model.length > 0
    && typeof opts.sessionId === "string" && opts.sessionId.length > 0;
}

Try / catch

try {
  const result = cave.assemble(opts);
} catch (e) {
  if (e.message.includes("requires model and sessionId")) {
    // fix options: supply model/sessionId before retrying
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `cave.assemble({ provider, slots, ... })` (or `Cave.assemble`) with `options.model` undefined/empty string, `options.sessionId` undefined/empty string, or both — e.g. an options object built dynamically where model comes from an unset config value.

Common situations: Assembling requests in a loop where the model name is read from an env var or config that was never set; refactoring call sites and forgetting sessionId when it was previously inferred elsewhere; constructing AssembleOptions from user input that omits fields; TypeScript `as` casts or JS callers bypassing the type checker.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/aad2b69018dfc5cb. Report an issue: GitHub.

Appendix: source

Thrown at packages/sdk/typescript/src/index.ts:1816

  return {
    items: selectedIDs.map((id) => byID.get(id)!),
    tokensUsed,
    tokensBefore,
    tokensSaved,
    deferredCount,
    deferredIds: [...deferredIDs],
    basis: "inferred"
  };
}

const assemblyHashLedgers = new WeakMap<Cave, Map<string, string>>();
const assemblyRequestHeaders = new WeakMap<object, string>();

function assemble(cave: Cave, options: AssembleOptions): AssemblyResult {
  const provider = options.provider.trim().toLowerCase();
  const emitCacheHints = options.emitCacheHints ?? "gateway";
  if (!options.model || !options.sessionId) throw new Error("assemble requires model and sessionId");
  if (!["gateway", "self", "none"].includes(emitCacheHints)) {
    throw new Error(`unknown emitCacheHints value ${JSON.stringify(emitCacheHints)}`);
  }

  const ids = new Set<string>();
  let ledger = assemblyHashLedgers.get(cave);
  if (!ledger) {
    ledger = new Map<string, string>();
    assemblyHashLedgers.set(cave, ledger);
  }
  const normalized = options.slots.map((slot) => {
    if (!slot.id || ids.has(slot.id)) throw new Error(`assembly slot id must be non-empty and unique: ${JSON.stringify(slot.id)}`);
    ids.add(slot.id);
    if (!["stable", "session", "volatile"].includes(slot.stability)) {
      throw new Error(`assembly slot ${JSON.stringify(slot.id)} has unknown stability ${JSON.stringify(slot.stability)}`);
    }
    let contentJSON: string;
    try {

View on GitHub (pinned to 3ee70a1026)