{"record":{"id":"be657dae78d8a602","repo":"sgl-project/sglang","slug":"cannot-mix-lambda-extractor-with-static-kwargs","errorCode":null,"errorMessage":"cannot mix lambda extractor with static kwargs","messagePattern":"cannot mix lambda extractor with static kwargs","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/debug_utils/dumper.py","lineNumber":375,"sourceCode":"            k: v for k, v in (self._state.global_ctx | kwargs).items() if v is not None\n        }\n\n    def ctx(\n        self,\n        _extractor: Optional[Callable[..., dict]] = None,\n        **static_ctx: Any,\n    ) -> Callable:\n        \"\"\"Decorator that sets context before calling the wrapped function and clears it after.\n\n        Two forms:\n            @dumper.ctx(lambda self: dict(layer_id=self.layer_id))\n            def forward(self, x): ...\n\n            @dumper.ctx(phase=\"decode\")\n            def decode_step(self, x): ...\n        \"\"\"\n        if _extractor is not None and static_ctx:\n            raise ValueError(\"cannot mix lambda extractor with static kwargs\")\n        if _extractor is None and not static_ctx:\n            raise ValueError(\"must provide either a lambda or static kwargs\")\n\n        def decorator(fn: Callable) -> Callable:\n            @functools.wraps(fn)\n            def wrapper(*args: Any, **kwargs: Any) -> Any:\n                ctx_dict: dict = _extractor(args[0]) if _extractor else static_ctx\n                self.set_ctx(**ctx_dict)\n                try:\n                    return fn(*args, **kwargs)\n                finally:\n                    self.set_ctx(**{k: None for k in ctx_dict})\n\n            return wrapper\n\n        return decorator\n\n    def apply_source_patches(self) -> None:","sourceCodeStart":357,"sourceCodeEnd":393,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/debug_utils/dumper.py#L357-L393","documentation":"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.","triggerScenarios":"@dumper.ctx(lambda self: {...}, phase='decode') — a lambda plus static kwargs in the same decoration.","commonSituations":"Copy-pasting decorator examples and merging the two styles; refactoring from static kwargs to a lambda extractor while leaving old kwargs behind.","solutions":["Remove the static kwargs and put everything inside the lambda's returned dict","Or remove the lambda and keep only static kwargs"],"exampleFix":"# before\n@dumper.ctx(lambda self: {\"layer\": self.name}, phase=\"decode\")\ndef step(self, x): ...\n# after\n@dumper.ctx(lambda self: {\"layer\": self.name, \"phase\": \"decode\"})\ndef step(self, x): ...","handlingStrategy":"validation","validationCode":"import inspect\n# ensure decorator called with exactly one style\nassert not (positional_extractor and static_kwargs), \"pick one ctx style\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never mix a lambda extractor with static kwargs in @dumper.ctx","Codify the chosen style in one shared helper/wrapper for your codebase"],"tags":["decorator","api-misuse","debug-utils"],"backgroundTag":"invalid-arguments","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}