sgl-project/sglang · error · TypeError

{name} must be True / False / str / list[str], got {value!r}

Error message

{name} must be True / False / str / list[str], got {value!r}

What it means

_normalize_selector validates the same_params/same_results options of rank_consensus: each must be True, False, a single parameter-name string, or a list of strings. Anything else (None, int, nested lists, mixed-type lists) raises TypeError naming the offending option.

Source

Thrown at python/sglang/srt/utils/rank_consensus_checker.py:166

        return decorator


def _normalize_selector(
    value: None | bool | str | list[str], name: str
) -> None | bool | list[str]:
    """Normalize a selector argument to one of:
    ``None`` (skip), ``True`` (compare everything), or ``list[str]`` (the
    expressions to evaluate). ``False`` is treated as ``None``.
    """
    if value is None or value is False:
        return None
    if value is True:
        return True
    if isinstance(value, str):
        return [value]
    if isinstance(value, list) and all(isinstance(s, str) for s in value):
        return list(value)
    raise TypeError(f"{name} must be True / False / str / list[str], got {value!r}")


def _is_method_with_receiver(func: Any) -> bool:
    """Return True iff ``func`` is a method whose first parameter is a
    receiver (instance for instance-methods, class for class-methods) that
    should be dropped from the ``same_params=True`` payload.

    Distinguishes:
      * ``staticmethod`` object  -> False (no receiver)
      * ``classmethod``  object  -> True  (receiver is the class)
      * plain ``def`` defined inside a class body (``__qualname__`` has a
        dot before the final segment and is not a ``<locals>`` closure) ->
        True  (instance method)
      * anything else (module-level function, nested function, lambda) ->
        False
    """
    if isinstance(func, staticmethod):
        return False

View on GitHub (pinned to 0132848349)

Solutions

  1. Use booleans or parameter-name strings/lists of strings only
  2. Coerce config values: None -> False, ensure list elements are strings
  3. Validate options before applying the decorator when they come from dynamic config

Example fix

# before
@rank_consensus(same_params=None)
def fn(): ...
# after
@rank_consensus(same_params=False)
def fn(): ...
Defensive patterns

Strategy: validation

Validate before calling

def valid_selector(v) -> bool:
    return v is True or v is False or isinstance(v, str) or (isinstance(v, list) and all(isinstance(s, str) for s in v))

Type guard

def is_selector(v) -> bool:
    return v is True or v is False or isinstance(v, str) or (isinstance(v, list) and all(isinstance(x, str) for x in v))

Try / catch

try:
    rank_consensus(same_params=opt)
except TypeError as e:
    if 'must be True / False / str / list[str]' in str(e):
        opt = bool(opt); rank_consensus(same_params=opt)

Prevention

When it happens

Trigger: @rank_consensus(same_params=None), same_params=1, or same_params=['a', 2] where a list contains non-strings.

Common situations: Config-driven decorator options parsed from YAML/JSON where a value becomes None or a non-string type; typos intending True.

Related errors


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