sgl-project/sglang · error · ValueError
layer_types has {len(self.layer_types)} entries but num_hidd
Error message
layer_types has {len(self.layer_types)} entries but num_hidden_layers is {self.num_hidden_layers} What it means
When layer_types is explicitly provided it must have exactly num_hidden_layers entries, one per transformer layer. The validator only derives layer_types from no_rope_layers when it is None; otherwise the length is checked against num_hidden_layers and this error fires on mismatch.
Source
Thrown at python/sglang/srt/hardware_backend/mlx/models/muse_glimmer_mlx.py:297
f"num_hidden_layers is {self.num_hidden_layers}"
)
bad_flags = sorted(set(self.no_rope_layers) - {0, 1})
if bad_flags:
raise ValueError(
f"no_rope_layers contains non-binary entries {bad_flags}; "
"each entry must be 0 (NoPE) or 1 (RoPE)"
)
# NoPE layers are the full-attention layers; the rest slide.
derived_layer_types = [
"full_attention" if rope_flag == 0 else "sliding_attention"
for rope_flag in self.no_rope_layers
]
if self.layer_types is None:
self.layer_types = derived_layer_types
else:
if len(self.layer_types) != self.num_hidden_layers:
raise ValueError(
f"layer_types has {len(self.layer_types)} entries but "
f"num_hidden_layers is {self.num_hidden_layers}"
)
bad = sorted(
set(self.layer_types) - {"full_attention", "sliding_attention"}
)
if bad:
raise ValueError(
f"layer_types contains unknown entries {bad}; expected only "
"'full_attention' or 'sliding_attention'"
)
if self.layer_types != derived_layer_types:
mismatches = [
i
for i, (got, want) in enumerate(
zip(self.layer_types, derived_layer_types)
)
if got != wantView on GitHub (pinned to 0132848349)
Solutions
- Either omit layer_types so it is derived from no_rope_layers
- Or pad/trim layer_types so len == num_hidden_layers
- Verify num_hidden_layers matches the actual checkpoint depth before loading
Example fix
// before (num_hidden_layers=24, but only 12 entries) "layer_types": ["full_attention", "sliding_attention", ...12 total] // after "layer_types": null // derived from no_rope_layers
Defensive patterns
Strategy: validation
Validate before calling
assert cfg.get("layer_types") is None or len(cfg["layer_types"]) == cfg["num_hidden_layers"] Type guard
def layer_types_len_ok(cfg: dict) -> bool:
lt = cfg.get("layer_types")
return lt is None or (isinstance(lt, list) and len(lt) == cfg["num_hidden_layers"]) Prevention
- Prefer omitting layer_types and letting it derive from no_rope_layers
- Update both fields together when changing depth
When it happens
Trigger: Passing a layer_types list whose len differs from num_hidden_layers — e.g. truncating the list, adding an entry, or using a layer_types array copied from a model with a different layer count.
Common situations: Copying config.json between model variants (7B vs 3B with different depths), editing num_hidden_layers without updating layer_types, or partial manual merges of configs.
Related errors
- no_rope_layers contains non-binary entries {bad_flags}; each
- layer_types contains unknown entries {bad}; expected only 'f
- layer_types disagrees with no_rope_layers (NoPE layers must
- bad compress_ratio {compress_ratio}
- The requested FlashAttention forward configuration exceeds S
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/316caa5d20562505.
Report an issue: GitHub.