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
- Pass a non-empty `model` string (e.g. "claude-sonnet-4") and a non-empty `sessionId` in the AssembleOptions object.
- If the model is dynamic, validate the config/env value before calling assemble and substitute a default.
- Generate a sessionId explicitly (crypto.randomUUID()) if your workflow has no natural session id.
- 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
- Always construct AssembleOptions through a single factory that asserts model and sessionId.
- Default sessionId to crypto.randomUUID() in the factory.
- Avoid `as` casts on partial option objects; let the type checker flag omissions.
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
- unknown emitCacheHints value
- artifact_id is required
- artifactId is required
- assemble requires model and session_id
- assembly slot id must be non-empty and unique
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)