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

  1. Inspect self.no_rope_layers and normalize every entry to int(v) if booleans/strings were intended
  2. Fix the upstream config.json so every entry is exactly 0 or 1
  3. 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

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


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