{"record":{"id":"a2a0e361cea5a0c7","repo":"sgl-project/sglang","slug":"auxiliary-pp-tensor-names-must-be-non-empty-string","errorCode":null,"errorMessage":"auxiliary PP tensor names must be non-empty strings","messagePattern":"auxiliary PP tensor names must be non-empty strings","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/sampling/sampling_observer_pp.py","lineNumber":52,"sourceCode":"\ndef add_auxiliary_output_to_pp_tensors(\n    tensors: MutableMapping[str, Any],\n    output: Optional[DeviceAuxiliaryOutput],\n) -> None:\n    if output is None:\n        return\n    if not isinstance(output, PipelineParallelAuxiliaryOutput):\n        raise RuntimeError(\n            \"auxiliary output does not support pipeline-parallel transport\"\n        )\n\n    output_tensors = output.to_pp_tensors()\n    if not output_tensors:\n        raise RuntimeError(\"auxiliary PP output must contain at least one tensor\")\n\n    for name, tensor in output_tensors.items():\n        if not isinstance(name, str) or not name:\n            raise RuntimeError(\"auxiliary PP tensor names must be non-empty strings\")\n        if not torch.is_tensor(tensor):\n            raise RuntimeError(f\"auxiliary PP output {name!r} is not a tensor\")\n        key = f\"{_OUTPUT_PREFIX}{name}\"\n        if key in tensors:\n            raise RuntimeError(f\"duplicate auxiliary PP tensor {name!r}\")\n        tensors[key] = tensor\n\n\ndef pop_auxiliary_output_from_pp_tensors(\n    tensors: MutableMapping[str, Any],\n    observer: Optional[SamplingObserver],\n) -> Optional[DeviceAuxiliaryOutput]:\n    output_tensors = {\n        key.removeprefix(_OUTPUT_PREFIX): value\n        for key, value in tensors.items()\n        if key.startswith(_OUTPUT_PREFIX)\n    }\n    if not output_tensors:","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/sampling/sampling_observer_pp.py#L34-L70","documentation":"A key in the to_pp_tensors() mapping is not a non-empty string, so it cannot be namespaced into the PP tensor dict with the output prefix.","triggerScenarios":"An auxiliary output whose to_pp_tensors() returns a dict with None, empty, or non-str keys (e.g. ints or enum keys).","commonSituations":"Custom implementation using enum/int keys or tuple keys in the tensor mapping.","solutions":["Make to_pp_tensors() return Mapping[str, torch.Tensor] with non-empty string keys","Add a unit test asserting all keys are non-empty strings"],"exampleFix":"# before\ndef to_pp_tensors(self):\n    return {0: self.hidden}\n# after\ndef to_pp_tensors(self):\n    return {\"hidden\": self.hidden}","handlingStrategy":"validation","validationCode":"t = output.to_pp_tensors()\nassert all(isinstance(k, str) and k for k in t)","typeGuard":"def valid_pp_keys(t: dict) -> bool:\n    return all(isinstance(k, str) and k for k in t)","tryCatchPattern":null,"preventionTips":["Type to_pp_tensors() as Mapping[str, torch.Tensor] with mypy","Use plain string keys, never enums/ints"],"tags":["pipeline-parallel","sampling","validation","keys"],"backgroundTag":"payload-schema-validation","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}