{"record":{"id":"78bd30fe8b9bdade","repo":"sgl-project/sglang","slug":"name-r-is-not-a-config-leaf-no-ns-namespace","errorCode":null,"errorMessage":"{name!r} is not a config leaf (no NS namespace)","messagePattern":"(.+?) is not a config leaf \\(no NS namespace\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/runtime_context.py","lineNumber":938,"sourceCode":"        for bag, name, value in targets:\n            bag._set(name, value)\n        self._overrides_log.append((source, dict(fields)))\n\n    def config_leaf(self, name: str):\n        \"\"\"One resolved config leaf by field name — the read side of ``override``.\n\n        Callers that hold a field name rather than a namespace (a readback\n        endpoint, a control-plane handler) would otherwise have to know which\n        bag it lives in.\n        \"\"\"\n        bags = self._config_bags\n        if bags is None:\n            raise ValueError(\"config not published; cannot read a config leaf\")\n        from sglang.srt.arg_groups.arg_utils import namespace_of\n\n        path = namespace_of(type(self._server_args)).get(name)\n        if path is None:\n            raise ValueError(f\"{name!r} is not a config leaf (no NS namespace)\")\n        parts = path.split(\".\")\n        bag = self.config_bag(parts[0])\n        for seg in parts[1:]:\n            bag = object.__getattribute__(bag, \"_subs\").get(seg)\n            if bag is None:\n                raise ValueError(f\"subgroup {seg!r} missing under {path!r}\")\n        return getattr(bag, name)\n\n    def overrides_log(self) -> list:\n        \"\"\"Provenance of post-publish ``override`` calls: ``[(source, {field: value})]``.\n\n        Returns deep-ish copies (source, dict(fields)) so callers inspecting the\n        log cannot mutate the recorded provenance in place.\"\"\"\n        return [(source, dict(fields)) for source, fields in self._overrides_log]\n\n    def resolved_server_args_dict(self, base: dict | None = None) -> dict:\n        \"\"\"Serialize the *resolved* config: the pristine ``server_args`` fields\n        with every post-publish ``override`` overlaid.","sourceCodeStart":920,"sourceCodeEnd":956,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/runtime_context.py#L920-L956","documentation":"config_leaf resolves the field name via namespace_of(ServerArgs), which maps each dataclass field to its namespaced config path. If the field has no NS namespace mapping (it is not a published config leaf), the lookup returns None and this ValueError is raised. It means the name you asked for is either misspelled or is not part of the namespaced config surface.","triggerScenarios":"Calling ctx.config_leaf(\"tp_size\") when the actual ServerArgs field is named differently (e.g. tensor_parallel_size), asking for a ServerArgs field deliberately excluded from the NS namespace mapping, or passing a plain non-field attribute name.","commonSituations":"Typos in readback/control-plane endpoints that take a field name from a request; fields renamed across a version upgrade so the old name is no longer a config leaf; passing a private attribute or cache name.","solutions":["Check namespace_of(ServerArgs).keys() for the exact published field name and use it","Verify the field still exists on ServerArgs (typo or renamed field)","If the value genuinely is not a config leaf, read it from the ServerArgs object directly rather than config_leaf"],"exampleFix":"# before\nvalue = ctx.config_leaf(\"tp_size\")\n# after\nfrom sglang.srt.arg_groups.arg_utils import namespace_of\nfrom sglang.srt.server_args import ServerArgs\nassert \"tensor_parallel_size\" in namespace_of(ServerArgs)\nvalue = ctx.config_leaf(\"tensor_parallel_size\")","handlingStrategy":"validation","validationCode":"from sglang.srt.arg_groups.arg_utils import namespace_of\nfrom sglang.srt.server_args import ServerArgs\nif name not in namespace_of(ServerArgs):\n    raise KeyError(f\"{name} is not a config leaf\")\nvalue = ctx.config_leaf(name)","typeGuard":"def is_config_leaf(name: str) -> bool:\n    from sglang.srt.arg_groups.arg_utils import namespace_of\n    from sglang.srt.server_args import ServerArgs\n    return name in namespace_of(ServerArgs)","tryCatchPattern":null,"preventionTips":["Validate caller-supplied field names against namespace_of(ServerArgs) before passing them on","When upgrading sglang versions, grep call sites for renamed ServerArgs fields"],"tags":["config","typo","field-mapping","sglang"],"backgroundTag":"invalid-config-key","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}