JuliusBrussee/caveman · error
unknown emitCacheHints value
Error message
unknown emitCacheHints value ${JSON.stringify(emitCacheHints)} What it means
assemble() accepts an optional `emitCacheHints` option that defaults to "gateway" and must be one of "gateway", "self", or "none". Any other value — including typos and wrong-cased strings — is rejected with this Error before any assembly work. It is a strict enum guard on the cache-hint emission policy.
Solutions
- Set emitCacheHints to exactly "gateway", "self", or "none" (lowercase).
- Normalize the value yourself before calling: `hints.trim().toLowerCase()` if it originates from config or env.
- Omit the option entirely to get the "gateway" default.
- Type the variable as the exported EmitCacheHints union so invalid values fail at compile time.
Example fix
// before
cave.assemble({ ..., emitCacheHints: process.env.HINTS as string });
// after
const HINTS = ["gateway", "self", "none"] as const;
type Hints = typeof HINTS[number];
const raw = (process.env.HINTS ?? "gateway").toLowerCase() as Hints;
if (!HINTS.includes(raw)) throw new Error(`bad HINTS: ${process.env.HINTS}`);
cave.assemble({ ..., emitCacheHints: raw }); Defensive patterns
Strategy: validation
Validate before calling
const EMIT_CACHE_HINTS = new Set(["gateway", "self", "none"]);
function validHints(v) { return v === undefined || EMIT_CACHE_HINTS.has(v); } Type guard
function isEmitCacheHints(v) {
return v === undefined || v === "gateway" || v === "self" || v === "none";
} Try / catch
try {
return cave.assemble(opts);
} catch (e) {
if (e.message.startsWith("unknown emitCacheHints")) {
opts.emitCacheHints = "gateway"; // safe default
return cave.assemble(opts);
}
throw e;
} Prevention
- Lowercase and trim values coming from env/config before assigning emitCacheHints.
- Type the field with the EmitCacheHints union so invalid literals fail compilation.
- Rely on the "gateway" default instead of setting the option ad hoc.
When it happens
Trigger: Calling assemble() with `emitCacheHints` set to any string not in ["gateway","self","none"] — e.g. "Gateway", "gateway-hints", "cache", or a value read from config/env with unexpected casing or whitespace (note: `emitCacheHints` is used verbatim, only `provider` is lowercased).
Common situations: Mapping an env var like EMIT_CACHE_HINTS=Gateway straight into options; typos like "none" vs "off"; copying an option name from a different SDK version where the enum values differed; JSON config files with inconsistent casing.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- assemble requires model and sessionId
- assembly slot has unknown stability
- assembly slot has unknown stability
- artifactId is required
- assemble requires model and session_id
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/6a1cb35cf9e9d585.
Report an issue: GitHub.
Appendix: source
Thrown at packages/sdk/typescript/src/index.ts:1818
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 {
contentJSON = canonicalJSON(slot.content);
} catch {View on GitHub (pinned to 3ee70a1026)