sgl-project/sglang · error · ValueError

cannot mix lambda extractor with static kwargs

Error message

cannot mix lambda extractor with static kwargs

What it means

The dumper.ctx decorator accepts either a lambda extractor (positional) or static keyword context — but not both. If a callable is passed as _extractor AND static kwargs are provided, the decorator refuses to build the wrapper because the context source would be ambiguous.

Source

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

            k: v for k, v in (self._state.global_ctx | kwargs).items() if v is not None
        }

    def ctx(
        self,
        _extractor: Optional[Callable[..., dict]] = None,
        **static_ctx: Any,
    ) -> Callable:
        """Decorator that sets context before calling the wrapped function and clears it after.

        Two forms:
            @dumper.ctx(lambda self: dict(layer_id=self.layer_id))
            def forward(self, x): ...

            @dumper.ctx(phase="decode")
            def decode_step(self, x): ...
        """
        if _extractor is not None and static_ctx:
            raise ValueError("cannot mix lambda extractor with static kwargs")
        if _extractor is None and not static_ctx:
            raise ValueError("must provide either a lambda or static kwargs")

        def decorator(fn: Callable) -> Callable:
            @functools.wraps(fn)
            def wrapper(*args: Any, **kwargs: Any) -> Any:
                ctx_dict: dict = _extractor(args[0]) if _extractor else static_ctx
                self.set_ctx(**ctx_dict)
                try:
                    return fn(*args, **kwargs)
                finally:
                    self.set_ctx(**{k: None for k in ctx_dict})

            return wrapper

        return decorator

    def apply_source_patches(self) -> None:

View on GitHub (pinned to 0132848349)

Solutions

  1. Remove the static kwargs and put everything inside the lambda's returned dict
  2. Or remove the lambda and keep only static kwargs

Example fix

# before
@dumper.ctx(lambda self: {"layer": self.name}, phase="decode")
def step(self, x): ...
# after
@dumper.ctx(lambda self: {"layer": self.name, "phase": "decode"})
def step(self, x): ...
Defensive patterns

Strategy: validation

Validate before calling

import inspect
# ensure decorator called with exactly one style
assert not (positional_extractor and static_kwargs), "pick one ctx style"

Prevention

When it happens

Trigger: @dumper.ctx(lambda self: {...}, phase='decode') — a lambda plus static kwargs in the same decoration.

Common situations: Copy-pasting decorator examples and merging the two styles; refactoring from static kwargs to a lambda extractor while leaving old kwargs behind.

Related errors


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