{"record":{"id":"1098c1a982bdbb55","repo":"sgl-project/sglang","slug":"length-mismatch-details","errorCode":null,"errorMessage":"Length mismatch: {details}","messagePattern":"Length mismatch: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/debug_utils/comparator/utils.py","lineNumber":20,"sourceCode":"\nimport functools\nimport re\nfrom pathlib import Path\nfrom typing import TYPE_CHECKING, Callable, Generic, Optional, Tuple, TypeVar\n\nimport torch\nfrom pydantic import BaseModel, ConfigDict\n\n_T = TypeVar(\"_T\")\n_U = TypeVar(\"_U\")\n\n\ndef _check_equal_lengths(**named_lists: list) -> None:\n    lengths: dict[str, int] = {name: len(lst) for name, lst in named_lists.items()}\n    unique: set[int] = set(lengths.values())\n    if len(unique) > 1:\n        details: str = \", \".join(f\"{name}={length}\" for name, length in lengths.items())\n        raise ValueError(f\"Length mismatch: {details}\")\n\n\ndef auto_descend_dir(directory: Path, label: str) -> Path:\n    \"\"\"If directory has no .pt files but exactly one subdirectory does, descend into it.\n\n    Raises ValueError when the layout is ambiguous (>=2 subdirs with .pt)\n    or when no .pt data is found at all.\n    \"\"\"\n    if any(directory.glob(\"*.pt\")):\n        return directory\n\n    candidates: list[Path] = [\n        sub for sub in directory.iterdir() if sub.is_dir() and any(sub.glob(\"*.pt\"))\n    ]\n\n    if len(candidates) >= 2:\n        names: str = \", \".join(sorted(c.name for c in candidates))\n        raise ValueError(","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/debug_utils/comparator/utils.py#L2-L38","documentation":"_check_equal_lengths raises this when parallel lists passed as keyword arguments have differing lengths. It is used by dataclass __post_init__ / _validate_fields to enforce that field lists that are zipped together (names, tensors, etc.) stay in sync, and reports each list's name=length pair.","triggerScenarios":"Constructing a comparator dataclass with e.g. names=[...3 items...] and tensors=[...2 items...]; any _check_equal_lengths(a=[...], b=[...]) call where lengths differ.","commonSituations":"Building the record from partially-populated sources, filtering one list but not its sibling, or appending to one list during a loop but not the other.","solutions":["Audit the reported name=length pairs and fix the source that produced the short/long list","If filtering one list, apply the same mask to all parallel lists","Add an assert len(a)==len(b) at the point the lists are built"],"exampleFix":"# before\nRecord(names=['a','b','c'], tensors=[t0,t1])\n# after\nRecord(names=['a','b','c'], tensors=[t0,t1,t2])","handlingStrategy":"type-guard","validationCode":"def assert_parallel_lists(**lists):\n    lengths = {k: len(v) for k, v in lists.items()}\n    assert len(set(lengths.values())) == 1, lengths","typeGuard":"def lengths_equal(*lists) -> bool:\n    return len({len(l) for l in lists}) <= 1","tryCatchPattern":"try:\n    rec = Record(names=names, tensors=tensors)\nexcept ValueError as e:\n    print(e); raise","preventionTips":["Apply any filter/mask to all parallel lists together","Assert equal lengths at construction sites, not just in the dataclass"],"tags":["validation","length-mismatch","dataclass","invariants"],"backgroundTag":"collection-length-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}