sgl-project/sglang · error · TypeError

{cls_name}.{f.name}: expected {expected.__name__}, got {type

Error message

{cls_name}.{f.name}: expected {expected.__name__}, got {type(value).__name__}

What it means

_verify_types (run from a dataclass's __post_init__) raises this TypeError when an Optional field's non-None value's runtime type doesn't match the declared (unwrapped) type hint. It enforces strict runtime type checking on construction of the dumper config/record classes.

Source

Thrown at python/sglang/srt/debug_utils/dumper.py:45

# -------------------------------------- config base ------------------------------------------


@dataclass(frozen=True)
class _BaseConfig(ABC):
    def __post_init__(self) -> None:
        self._verify_types()

    def _verify_types(self) -> None:
        hints = get_type_hints(type(self))
        cls_name = type(self).__name__
        for f in fields(self):
            value = getattr(self, f.name)
            if value is None:
                continue
            expected = self._unwrap_type(hints[f.name])
            if not isinstance(value, expected):
                raise TypeError(
                    f"{cls_name}.{f.name}: expected {expected.__name__}, "
                    f"got {type(value).__name__}"
                )

    @classmethod
    @abstractmethod
    def _env_prefix(cls) -> str: ...

    @classmethod
    def _env_name(cls, field_name: str) -> str:
        return f"{cls._env_prefix()}{field_name.upper()}"

    @classmethod
    def from_env(cls) -> "_BaseConfig":
        return cls(
            **{
                f.name: cls._parse_env_field(cls._env_name(f.name), f.default)
                for f in fields(cls)

View on GitHub (pinned to 0132848349)

Solutions

  1. Coerce values to the declared types before constructing (int(...), str(...), list(...), Path(...))
  2. If loading from JSON, add a normalization step for numeric/boolean fields
  3. If the stricter contract is wrong for your use, change the field's type hint rather than bypassing the check

Example fix

# before
cfg = DumpConfig(top_k="5", out=Path('d'))
# after
cfg = DumpConfig(top_k=5, out=Path('d'))
Defensive patterns

Strategy: type-guard

Validate before calling

from dataclasses import fields, get_type_hints

def coerce(cfg_cls, **kwargs):
    hints = get_type_hints(cfg_cls)
    out = {}
    for f in fields(cfg_cls):
        v = kwargs.get(f.name)
        t = hints[f.name]
        if v is not None and not isinstance(v, t):
            v = t(v)  # naive coercion for primitives/Path/list
        out[f.name] = v
    return cfg_cls(**out)

Type guard

def is_optional_type(value, tp) -> bool:
    return value is None or isinstance(value, tp)

Try / catch

try:
    cfg = DumpConfig(**raw)
except TypeError as e:
    print(e); raise  # fix the offending field named in the message

Prevention

When it happens

Trigger: Constructing the dataclass with a wrong-typed value, e.g. a field typed Optional[int] receiving a string '3', or Optional[list[str]] receiving a tuple; None values are skipped.

Common situations: Loading config from JSON/YAML where numbers arrive as strings, passing Path vs str interchangeably, or CLI parsing that yields strings for numeric fields.

Related errors


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