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
- Pass 'secondary' as an object of knob overrides (e.g. {"secondary": {"cfg": 1.0}}) or omit it entirely.
- Fix the client schema that types 'secondary' as bool/number.
- 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
- Model 'secondary' as an object of knobs, never a flag.
- Generate request payloads from typed dataclasses/Pydantic models.
- Document the nested cache_dit_params shape in client SDKs.
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
- cache_dit_params must be a dict, got {type(raw).__name__}.
- Unknown cache_dit_params['secondary'] keys: {sorted(unknown)
- Unknown cache_dit_params keys: {sorted(unknown)}. Valid keys
- spt must be a bool when provided
- Unknown type: {type(other)}
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/3fecb4f012c64168.
Report an issue: GitHub.