You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug(web): Intermediate directory nodes in buildFileTree receive child leaf paths instead of directory paths #1707
In packages/web/src/features/git/utils.ts, buildFileTree constructs a nested FileTreeNode hierarchy from a flat list of { type, path } objects.
When creating intermediate directory nodes (lines 68-74), the new node's path property is assigned item.path (the full path of the current leaf file being processed), instead of the path of that directory:
Broken Folder State & Expansion in UI: In packages/web/src/app/(app)/browse/components/fileTreePanel.tsx, folder expand/collapse state is tracked via openPaths.has(node.path) and route sync via pathParts.slice(0, i + 1).join('/'). Because directory nodes receive the child file's path instead of their own directory path, clicking folders or deep-linking to nested paths causes folder state tracking and auto-expansion to fail.
Public API Corruption: The getTree endpoint (/api/git/tree) returns FileTreeNode with corrupted directory paths to API consumers.
Reproduction
constflatList=[{type: 'blob',path: 'src/components/buttons/PrimaryButton.tsx'}];consttree=buildFileTree(flatList);constsrcDir=tree.children[0];console.log(srcDir.name);// "src"console.log(srcDir.path);// Expected "src", but Got "src/components/buttons/PrimaryButton.tsx"
Proposed Fix
Reconstruct the directory node's path using parts.slice(0, i + 1).join('/'):
For intermediate directory levels (i < parts.length - 1), this evaluates to the proper directory path (e.g. "src", "src/components"), and for leaf files (i === parts.length - 1), it matches item.path.
I will take this. The intermediate nodes will carry their own directory path (the joined parts up to that level) and the new test will assert folder-node paths on a nested tree.
I looked into this, and the buildFileTree behavior you describe is real if you call it directly with a list that only has files, e.g. [{ type: 'blob', path: 'src/a/b.ts' }]. In practice it doesn't affect the browse UI or /api/tree. The only caller, getTreeApi.ts, runs git ls-tree with the -t flag, which lists every folder before its contents. So each folder node is created from its own entry with the correct path, before any file underneath it is processed.
To confirm, I called /api/tree on app.sourcebot.dev for sourcebot-dev/sourcebot with several paths inputs: nested folders, a file path, leading and trailing slashes, multiple paths, and an empty list. Across about 700 nodes, every folder's path matched its actual location.
Closing as not reproducible, but feel free to reopen if you see this in the UI.
Activity
itsmunzir commentedon Oct 8, 2026
I will take this. The intermediate nodes will carry their own directory path (the joined parts up to that level) and the new test will assert folder-node paths on a nested tree.
brendan-kellam commentedon Oct 8, 2026
Thanks for the detailed write-up @riteshvish02!
I looked into this, and the
buildFileTreebehavior you describe is real if you call it directly with a list that only has files, e.g.[{ type: 'blob', path: 'src/a/b.ts' }]. In practice it doesn't affect the browse UI or/api/tree. The only caller,getTreeApi.ts, runsgit ls-treewith the-tflag, which lists every folder before its contents. So each folder node is created from its own entry with the correct path, before any file underneath it is processed.To confirm, I called
/api/treeon app.sourcebot.dev forsourcebot-dev/sourcebotwith severalpathsinputs: nested folders, a file path, leading and trailing slashes, multiple paths, and an empty list. Across about 700 nodes, every folder'spathmatched its actual location.Closing as not reproducible, but feel free to reopen if you see this in the UI.
fix(web): give implicit file-tree directories their own path (sourceb…
fix(web): give implicit file-tree directories their own path (sourceb…