{"record":{"id":"41e7f7701fb36c51","repo":"sgl-project/sglang","slug":"label-directory-directory-has-no-pt-files-at","errorCode":null,"errorMessage":"{label}: directory {directory} has no .pt files at top level and multiple subdirectories contain data ({names}). Please specify the exact subdirectory.","messagePattern":"(.+?): directory (.+?) has no \\.pt files at top level and multiple subdirectories contain data \\((.+?)\\)\\. Please specify the exact subdirectory\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/debug_utils/comparator/utils.py","lineNumber":38,"sourceCode":"        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(\n            f\"{label}: directory {directory} has no .pt files at top level \"\n            f\"and multiple subdirectories contain data ({names}). \"\n            f\"Please specify the exact subdirectory.\"\n        )\n\n    if len(candidates) == 0:\n        raise ValueError(\n            f\"{label}: no .pt files found in {directory} or any of its subdirectories.\"\n        )\n\n    resolved: Path = candidates[0]\n\n    from sglang.srt.debug_utils.comparator.log_sink import log_sink\n    from sglang.srt.debug_utils.comparator.output_types import InfoLog\n\n    log_sink.add(\n        InfoLog(\n            category=\"auto_descend\",","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/debug_utils/comparator/utils.py#L20-L56","documentation":"auto_descend_dir raises this when the given directory has no top-level .pt files and two or more subdirectories contain .pt files, making auto-descent ambiguous. The message lists the candidate subdirectory names and asks the user to point at the exact one.","triggerScenarios":"Calling run() (which calls auto_descend_dir) with a parent dump directory containing e.g. both 'tp2/' and 'tp4/' subdirs each holding .pt files; also directly via test_error_with_multiple_nonempty_children.","commonSituations":"A dump root holding multiple runs/rank-sharded subdirectories (different TP sizes, before/after dumps), so the tool cannot guess which run to compare.","solutions":["Pass the specific subdirectory path containing the run's .pt files instead of the parent","Or delete/move the stale sibling directories so only one candidate remains","Check the listed names in the message to pick the intended run"],"exampleFix":"# before\ncompare --dir runs/           # contains runs/tp2/*.pt and runs/tp4/*.pt\n# after\ncompare --dir runs/tp4/        # explicit subdirectory","handlingStrategy":"validation","validationCode":"from pathlib import Path\ndef unique_pt_child(d: Path):\n    cands = [p for p in d.iterdir() if p.is_dir() and any(p.glob('*.pt'))]\n    return cands[0] if len(cands) == 1 else (None if not cands else cands)","typeGuard":null,"tryCatchPattern":"try:\n    resolved = auto_descend_dir(directory, label)\nexcept ValueError as e:\n    print(e); sys.exit(2)  # pick a subdir from the listed names","preventionTips":["Pass the exact run subdirectory instead of a dump root","Keep one run per directory to keep auto-descent unambiguous"],"tags":["filesystem","ambiguity","directory-layout","dump"],"backgroundTag":"ambiguous-input-directory","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}