sgl-project/sglang · error · ValueError
no_rope_layers contains non-binary entries {bad_flags}; each
Error message
no_rope_layers contains non-binary entries {bad_flags}; each entry must be 0 (NoPE) or 1 (RoPE) What it means
The Muse Glimmer MLX config's no_rope_layers field must be a binary list where each entry is 0 (NoPE / no positional embedding) or 1 (RoPE). The post-init validator computes the set difference between the provided flags and {0,1} and throws if any non-binary values (e.g. 2, True/False mixed with ints is fine, but strings, None, or >1) are present.
Source
Thrown at python/sglang/srt/hardware_backend/mlx/models/muse_glimmer_mlx.py:283
f"num_attention_heads ({self.num_attention_heads}) must be a "
f"multiple of num_key_value_heads ({self.num_key_value_heads})"
)
derived_no_rope = [
0 if (self.num_hidden_layers - i - 1) % self.every_n_layers_nope == 0 else 1
for i in range(self.num_hidden_layers)
]
if self.no_rope_layers is None:
self.no_rope_layers = derived_no_rope
else:
if len(self.no_rope_layers) != self.num_hidden_layers:
raise ValueError(
f"no_rope_layers has {len(self.no_rope_layers)} entries but "
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(View on GitHub (pinned to 0132848349)
Solutions
- Inspect self.no_rope_layers and normalize every entry to int(v) if booleans/strings were intended
- Fix the upstream config.json so every entry is exactly 0 or 1
- Regenerate the artifact with the matching packager if the config came from a mismatched toolchain
Example fix
// before "no_rope_layers": [0, 1, 2, 1] // after "no_rope_layers": [0, 1, 1, 1]
Defensive patterns
Strategy: validation
Validate before calling
flags = cfg.get("no_rope_layers", [])
assert all(v in (0, 1) for v in flags), f"non-binary entries: {sorted(set(flags) - {0,1})}" Type guard
def is_binary_layer_flags(v) -> bool:
return isinstance(v, list) and all(x in (0, 1) for x in v) Prevention
- Normalize no_rope_layers entries to ints right after loading config
- Never hand-edit the list; derive it from the model card metadata
When it happens
Trigger: Constructing the config dataclass (its __post_init__ runs automatically) with no_rope_layers containing values other than 0 or 1 — e.g. [0,1,2,...], ['0','1'], or booleans-as-strings loaded from a malformed config.json or hand-edited YAML.
Common situations: Hand-editing config.json and introducing typos, loading a config produced by a different/older packager that emitted layer-type strings or trinary flags, or programmatically deriving no_rope_layers from a formula that yields out-of-range values.
Related errors
- Invalid fused KV rotary/head dim pair: rotary_dim={rotary_di
- Invalid fused KV rotary/head dim pair: rotary_dim={self.rota
- RoPE config mismatch across layers for fused KV path: expect
- {rope_type=} not supported. Choose between 'interleaved' and
- memory_position_mode must be one of {'reference', 'legacy',
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/97797b39c5e85ad0.
Report an issue: GitHub.