sgl-project/sglang · error · ValueError

subgroup {seg!r} missing under {path!r}

Error message

subgroup {seg!r} missing under {path!r}

What it means

After resolving the field's dotted namespace path, config_leaf walks the sub-bags via bag._subs. If an intermediate subgroup named in the path is missing from the published bag tree, the traversal hits None and this error fires. It indicates the published projection is inconsistent with the namespace map — usually a registration or role-pruning bug, not a caller typo.

Source

Thrown at python/sglang/srt/runtime_context.py:944

        Callers that hold a field name rather than a namespace (a readback
        endpoint, a control-plane handler) would otherwise have to know which
        bag it lives in.
        """
        bags = self._config_bags
        if bags is None:
            raise ValueError("config not published; cannot read a config leaf")
        from sglang.srt.arg_groups.arg_utils import namespace_of

        path = namespace_of(type(self._server_args)).get(name)
        if path is None:
            raise ValueError(f"{name!r} is not a config leaf (no NS namespace)")
        parts = path.split(".")
        bag = self.config_bag(parts[0])
        for seg in parts[1:]:
            bag = object.__getattribute__(bag, "_subs").get(seg)
            if bag is None:
                raise ValueError(f"subgroup {seg!r} missing under {path!r}")
        return getattr(bag, name)

    def overrides_log(self) -> list:
        """Provenance of post-publish ``override`` calls: ``[(source, {field: value})]``.

        Returns deep-ish copies (source, dict(fields)) so callers inspecting the
        log cannot mutate the recorded provenance in place."""
        return [(source, dict(fields)) for source, fields in self._overrides_log]

    def resolved_server_args_dict(self, base: dict | None = None) -> dict:
        """Serialize the *resolved* config: the pristine ``server_args`` fields
        with every post-publish ``override`` overlaid.

        ``get_internal_state`` reports this, and ``/server_info`` carries it in
        the ``internal_states`` block, so scheduler-side runtime changes show up
        in a readback: HiCache attach/detach, the generated forward-pass-metrics
        endpoint, tunables set via ``/set_internal_state``.

View on GitHub (pinned to 0132848349)

Solutions

  1. Check the role's ROLE_NAMESPACE_SETS entry includes the namespace subgroup you are reading (or is None for the full tree)
  2. Verify the subgroup is registered in the bag-projection code path that builds _subs
  3. If the namespace map and bag construction are out of sync after a refactor, fix/report the projection upstream
Defensive patterns

Strategy: try-catch

Try / catch

try:
    value = ctx.config_leaf(name)
except ValueError as e:
    if "missing under" in str(e):
        raise RuntimeError(f"config bag tree inconsistent for {name}: {e}") from e
    raise

Prevention

When it happens

Trigger: A field whose namespace_of path is 'a.b.field' where the published bag for 'a' lacks sub-bag 'b'; publishing under a role whose ROLE_NAMESPACE_SETS entry prunes that subgroup out of the bag tree; adding a new namespace subgroup without registering it in the bag projection.

Common situations: Adding a new config subgroup in development and forgetting to register it where bags are built; running with SGLANG_ROLE_NAMESPACES=enforce and a role namespace set that excludes the subgroup you then try to read; desync between the namespace map and bag construction after a refactor.

Related errors


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