JuliusBrussee/caveman · error · ValueError
assembly slot id must be non-empty and unique
Error message
assembly slot id must be non-empty and unique: {slot.id!r} What it means
Every assembly slot must have a non-empty `id`, and slot ids within a single `assemble()` call must be unique. The library deduplicates content per slot id, so duplicates or blanks are rejected with this ValueError.
Solutions
- Give each slot a unique, non-empty `id` before calling `assemble()`.
- De-duplicate or rename slots when merging lists from multiple sources.
- Use deterministic, descriptive ids per logical role (e.g. "system", "tools", "history") so each appears once.
Example fix
// before
slots = [AssemblySlot("system", "stable", a), AssemblySlot("system", "stable", b)]
// after
slots = [AssemblySlot("system", "stable", a), AssemblySlot("tools", "session", b)] Defensive patterns
Strategy: validation
Validate before calling
ids = [s.id for s in opts.slots]
assert all(ids), "empty slot id"
assert len(ids) == len(set(ids)), f"duplicate slot ids: {ids}" Try / catch
try:
result = cave.assemble(opts)
except ValueError as e:
logger.error("slot id problem: %s", e)
raise Prevention
- Name slots by logical role and instantiate each once
- De-duplicate merged slot lists by id before assembling
- Reject empty slot ids in your slot-builder helper
When it happens
Trigger: Calling `assemble()` with a slot whose `id` is `""` or `None`, or listing two slots with the same id (e.g. two "system-prompt" slots in one options).
Common situations: Generating slot ids in a loop that defaults to a constant, or merging slot lists from two sources without de-duplicating.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- assemble requires model and session_id
- assembly slot has unknown stability
- artifact_id is required
- ASGI context resolver or request bounds are invalid
- assemble requires model and sessionId
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/74b0176340afdd3c.
Report an issue: GitHub.
Appendix: source
Thrown at packages/sdk/python/caveman_cloud/core.py:446
Pure client-side: no account and no network call. The hash ledger is
in-process and scoped by ``session_id``; deterministic slot content
across processes remains the builder's obligation.
``emit_cache_hints="gateway"`` (default) emits no provider hint so the
gateway optimizer retains attribution. ``"self"`` places provider
hints for direct calls but mints nothing.
"""
provider = options.provider.strip().lower()
if not options.model or not options.session_id:
raise ValueError("assemble requires model and session_id")
if options.emit_cache_hints not in {"gateway", "self", "none"}:
raise ValueError(f"unknown emit_cache_hints value {options.emit_cache_hints!r}")
ids: set[str] = set()
normalized: list[AssemblySlot] = []
for slot in options.slots:
if not slot.id or slot.id in ids:
raise ValueError(f"assembly slot id must be non-empty and unique: {slot.id!r}")
ids.add(slot.id)
if slot.stability not in {"stable", "session", "volatile"}:
raise ValueError(
f"assembly slot {slot.id!r} has unknown stability {slot.stability!r}"
)
try:
content_json = _canonical_json(slot.content)
content = json.loads(content_json)
except (TypeError, ValueError):
raise ValueError(
f"assembly slot {slot.id!r} content is not JSON-serializable"
) from None
if slot.stability != "volatile":
key = (options.session_id, slot.id)
content_hash = _sha256_hex(content_json)
with self._assembly_hash_lock:
previous = self._assembly_hash_ledger.get(key)
if previous is not None and previous != content_hash:View on GitHub (pinned to 3ee70a1026)