sgl-project/sglang · error · ValueError

cache_dit_params['secondary'] must be a dict, got {type(seco

Error message

cache_dit_params['secondary'] must be a dict, got {type(secondary).__name__}.

What it means

After the top-level key check, resolve_cache_dit_request_overrides inspects overrides.get('secondary'). If it is present (non-None) but not a dict, it raises this ValueError before ever looking at the knob keys.

Source

Thrown at python/sglang/multimodal_gen/runtime/cache/cache_dit_integration.py:239


def resolve_cache_dit_request_overrides(raw: dict | None) -> dict:
    """Validate cache_dit_params and return a copy; unknown keys fail the request."""
    if raw is None:
        return {}
    if not isinstance(raw, dict):
        raise ValueError(f"cache_dit_params must be a dict, got {type(raw).__name__}.")
    unknown = set(raw) - CACHE_DIT_REQUEST_PARAM_KEYS
    if unknown:
        raise ValueError(
            f"Unknown cache_dit_params keys: {sorted(unknown)}. "
            f"Valid keys: {sorted(CACHE_DIT_REQUEST_PARAM_KEYS)}."
        )
    overrides = dict(raw)
    secondary = overrides.get("secondary")
    if secondary is not None:
        if not isinstance(secondary, dict):
            raise ValueError(
                "cache_dit_params['secondary'] must be a dict, got "
                f"{type(secondary).__name__}."
            )
        unknown = set(secondary) - CACHE_DIT_REQUEST_KNOB_KEYS
        if unknown:
            raise ValueError(
                f"Unknown cache_dit_params['secondary'] keys: {sorted(unknown)}. "
                f"Valid keys: {sorted(CACHE_DIT_REQUEST_KNOB_KEYS)}."
            )
        overrides["secondary"] = dict(secondary)
    return overrides


def cache_dit_overrides_key(overrides: dict) -> tuple:
    """Hashable snapshot of request overrides, for mount-change detection."""

    def _freeze(value):
        if isinstance(value, dict):

View on GitHub (pinned to 0132848349)

Solutions

  1. Pass 'secondary' as an object of knob overrides (e.g. {"secondary": {"cfg": 1.0}}) or omit it entirely.
  2. Fix the client schema that types 'secondary' as bool/number.
  3. If you meant a top-level toggle, use one of the valid top-level keys from CACHE_DIT_REQUEST_PARAM_KEYS.

Example fix

// before
request(cache_dit_params={"secondary": true})
// after
request(cache_dit_params={"secondary": {"cfg": 1.0}})
Defensive patterns

Strategy: type-guard

Validate before calling

sec = (cache_dit_params or {}).get("secondary")
if sec is not None and not isinstance(sec, dict):
    raise TypeError("secondary must be a dict")

Type guard

def has_valid_secondary(params: dict) -> bool:
    sec = params.get("secondary")
    return sec is None or isinstance(sec, dict)

Try / catch

try:
    client.generate(prompt, cache_dit_params=params)
except ValueError as e:
    if "['secondary'] must be a dict" in str(e):
        params = {**params, "secondary": {}}
        retry(client.generate, prompt, cache_dit_params=params)
    raise

Prevention

When it happens

Trigger: Sending cache_dit_params={"secondary": true} or {"secondary": 2} — the key is valid, but its value is not a JSON object.

Common situations: Clients treating 'secondary' as a boolean enable flag; shorthand/flattened encodings; schema drift between client models and the server's expected nested dict.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/3fecb4f012c64168. Report an issue: GitHub.