JuliusBrussee/caveman · error · ValueError

unknown emit_cache_hints value

Error message

unknown emit_cache_hints value {options.emit_cache_hints!r}

What it means

`assemble()` accepts only `emit_cache_hints` values `"gateway"`, `"self"`, or `"none"`. Any other string raises this ValueError naming the offending value. The field controls where provider cache hint blocks are emitted.

Solutions

  1. Set `emit_cache_hints` to one of exactly "gateway", "self", or "none" (lowercase).
  2. Normalize/whitelist the value in your config layer before constructing options.
  3. Check the docstring of `assemble()` for the current allowed set if upgrading.

Example fix

// before
opts = AssembleOptions(..., emit_cache_hints="Gateway")
// after
opts = AssembleOptions(..., emit_cache_hints="gateway")
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = {"gateway", "self", "none"}
assert opts.emit_cache_hints in ALLOWED, opts.emit_cache_hints

Try / catch

try:
    result = cave.assemble(opts)
except ValueError as e:
    opts.emit_cache_hints = "gateway"
    result = cave.assemble(opts)

Prevention

When it happens

Trigger: Calling `assemble()` with `AssembleOptions(emit_cache_hints=...)` set to a misspelled or differently-cased value such as `"Gateway"`, `"auto"`, `True`, or `None` handled as a string.

Common situations: Typo after copy-paste, storing the setting in config as `"GATEWAY"`, or upgrading code from an older flag vocabulary.

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


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

Appendix: source

Thrown at packages/sdk/python/caveman_cloud/core.py:440

        """
        return RetryLoopBreaker(threshold=threshold)

    def assemble(self, options: AssembleOptions) -> AssemblyResult:
        """Build a provider request with stable/session content above volatile.

        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

View on GitHub (pinned to 3ee70a1026)