{"record":{"id":"37ab4e7bb3be344d","repo":"Graphify-Labs/graphify","slug":"root-root-matched-0-of-len-by-file-source-f","errorCode":null,"errorMessage":"--root {root} matched 0 of {len(by_file)} source files (source_file paths are stored repo-relative, e.g. {sample!r})","messagePattern":"--root (.+?) matched 0 of (.+?) source files \\(source_file paths are stored repo-relative, e\\.g\\. (.+?)\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"graphify/tree_html.py","lineNumber":169,"sourceCode":"        if len(sym_children) > max_children:\n            extra = len(sym_children) - max_children\n            sym_children = sym_children[:max_children] + [\n                _make_truncation_leaf(extra),\n            ]\n        file_node = {\n            \"name\": src_path.name,\n            \"total_count\": len(sym_children) or 1,\n            \"children\": sym_children,\n        }\n        parent_dir[\"children\"].append(file_node)\n\n    # An explicit --root that matches NOTHING would silently flatten the whole\n    # hierarchy (every file attaches to the root); the common case is passing an\n    # absolute checkout path while source_file is stored repo-relative (#2534).\n    # A PARTIAL match stays fine — files outside the root legitimately attach flat.\n    if explicit_root and matched_files == 0:\n        sample = min(by_file)\n        raise ValueError(\n            f\"--root {root} matched 0 of {len(by_file)} source files \"\n            f\"(source_file paths are stored repo-relative, e.g. {sample!r})\"\n        )\n\n    # Sort each dir's children + propagate total_count up.\n    def _finalise(d: Dict[str, Any]) -> int:\n        kids = d.get(\"children\") or []\n        kids.sort(key=lambda c: (\n            0 if (c.get(\"children\") and len(c[\"children\"]) > 0) else 1,\n            c[\"name\"].lower(),\n        ))\n        if not kids:\n            return d.get(\"total_count\") or 1\n        n = 0\n        for c in kids:\n            n += _finalise(c)\n        d[\"total_count\"] = n or 1\n        return d[\"total_count\"]","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/graphify/tree_html.py#L151-L187","documentation":"Raised in the tree builder (graphify/tree_html.py) when an explicitly passed --root matched zero of the source files being laid out. source_file paths in the graph are stored repo-relative, so passing an absolute checkout path (or any prefix that matches nothing) would otherwise silently flatten the whole tree with every file attached to the root; the guard turns that into an explicit error (#2534). A partial match is fine and does not raise.","triggerScenarios":"Invoking the tree/HTML export with --root /home/me/repos/project while nodes store source_file as 'src/foo.py' (relative), so the absolute prefix matches 0 of len(by_file) files; any --root whose string prefix does not overlap any stored path.","commonSituations":"Users habitually passing absolute paths on the command line; scripts generating --root from os.getcwd(); graphs built on one machine and rendered on another with a different checkout location.","solutions":["Pass the repo-relative prefix instead of an absolute path, e.g. --root src/ rather than /home/me/repo/src.","Compare your --root against the sample shown in the error message (min(by_file)) to see the expected path format.","If you meant 'no filter', drop --root entirely rather than guessing a root.","For embedding in HTML with a different base, remap source_file values before generating the tree."],"exampleFix":"# before\ngraphify tree-html --root /home/me/repos/project/src\n\n# after\ngraphify tree-html --root src","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\ndef root_matches_any(root: str, by_file: dict[str, dict]) -> int:\n    return sum(1 for f in by_file if f.startswith(root))\n\n# prefer repo-relative roots; reject ones that match nothing\nroot = \"src\" if root_matches_any(\"src\", by_file) else None","typeGuard":"def is_repo_relative_root(root: str, sample_file: str) -> bool:\n    # stored paths are repo-relative, so absolute roots never prefix-match\n    return not Path(root).is_absolute() and sample_file.startswith(root.split(\"/\")[0] + \"/\") is not None","tryCatchPattern":"try:\n    tree = build_tree(data, root=args.root)\nexcept ValueError as e:\n    if \"matched 0 of\" in str(e):\n        args.root = None  # no filter instead of a wrong absolute filter\n        tree = build_tree(data, root=args.root)\n    else:\n        raise","preventionTips":["Pass repo-relative prefixes to --root, never absolute checkout paths.","Print the stored sample path from the graph when debugging tree layout.","Omit --root when no filtering is intended."],"tags":["cli","paths","graph","html-export"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}