{"record":{"id":"c76a4334c0b2e504","repo":"sgl-project/sglang","slug":"must-provide-either-a-lambda-or-static-kwargs","errorCode":null,"errorMessage":"must provide either a lambda or static kwargs","messagePattern":"must provide either a lambda or static kwargs","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/debug_utils/dumper.py","lineNumber":377,"sourceCode":"\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:\n        \"\"\"Apply source patches from DUMPER_SOURCE_PATCHER_CONFIG if set.\n","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/debug_utils/dumper.py#L359-L395","documentation":"The dumper.ctx decorator requires exactly one context source: a lambda extractor or static keyword arguments. If neither is supplied, the wrapper would have no context to register, so the decorator fails fast at decoration time rather than silently doing nothing.","triggerScenarios":"@dumper.ctx() with no arguments decorating a method; calling dumper.ctx with no positional callable and no kwargs.","commonSituations":"Decorating a method intending to use a default context, or forgetting to pass the extractor lambda during a refactor.","solutions":["Pass a lambda extractor: @dumper.ctx(lambda self: {...})","Or pass at least one static kwarg: @dumper.ctx(phase='decode')"],"exampleFix":"# before\n@dumper.ctx\ndef step(self, x): ...\n# after\n@dumper.ctx(phase=\"decode\")\ndef step(self, x): ...","handlingStrategy":"validation","validationCode":"assert extractor is not None or bool(static_kwargs), \"ctx needs a lambda or static kwargs\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lint for bare @dumper.ctx with no arguments","Keep decorator usage examples next to the decorated class"],"tags":["decorator","api-misuse","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}