Skip to content

fix(web): show empty-state messages in the browse file-tree panel - #1531

Open
Harsh23Kashyap wants to merge 4 commits into
sourcebot-dev:mainfrom
Harsh23Kashyap:fix/empty-repo-tree-preview
Open

fix(web): show empty-state messages in the browse file-tree panel#1531
Harsh23Kashyap wants to merge 4 commits into
sourcebot-dev:mainfrom
Harsh23Kashyap:fix/empty-repo-tree-preview

Conversation

@Harsh23Kashyap

@Harsh23Kashyap Harsh23Kashyap commented Aug 2, 2026

Copy link
Copy Markdown

Summary

The browse file-tree panel previously rendered a blank scroll area when the folder contents were empty (e.g. for a freshly-created, uncommitted repository) and the generic "Error loading tree preview" text for service errors — including 404s from a typo in the repo name. Both are unhelpful.

Three changes that distinguish the cases and surface user-friendly messages:

  1. pureTreePreviewPanel.tsx: render "This directory is empty." when items.length === 0. Covers both the sub-directory and repo-root cases (a repo is just a directory at the root).
  2. treePreviewPanelClient.tsx: when the response is [] AND path === '', render a more emphatic "This repository is empty." message (no path header, no separator) that takes the full panel.
  3. treePreviewPanel.tsx: distinguish 404 from other service errors. A 404 now shows "Repository not found." instead of the generic "Error loading tree preview" — useful when a user hits a typo in a repo name.

Fixes #1530 (and addresses the user-reported screenshots in #821).

Files

  • packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/pureTreePreviewPanel.tsx — empty-state branch when items.length === 0.
  • packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanelClient.tsx — root-path-only "This repository is empty." message that takes the full panel.
  • packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanel.tsx — 404 distinction in the service-error branch.
  • packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/pureTreePreviewPanel.test.tsx — 1 new vitest case.
  • CHANGELOG.md — one-line entry under [Unreleased] → Fixed.

Why this is in scope

The user-facing issue is reported as confusing UX for an empty repository. The fix is purely a UI change — the data layer (getFolderContents) already returns [] for empty repos, and the getRepoInfoByName 404 is a real user-facing condition (typo, missing config) that's been confused with a sync error. No API, no schema, no migration.

Why three messages, not one

A single "This folder has no items" message would lose the distinction between the three cases the user is likely to encounter:

  • Empty repository at the root path: most actionable for a self-hosted operator — they probably just connected a fresh repo and the first sync hasn't run yet. The message says "Once a commit lands on the default branch, its files will appear here." which points them at the next step.
  • Empty sub-directory: less common but still a real case (e.g. a docs/ folder with no files). The "directory" copy is accurate without alarming the user.
  • 404 / repo not found: the user typed a typo in a URL. The "Repository not found." message is more actionable than the system-error lookalike.

Test coverage

1 vitest case in pureTreePreviewPanel.test.tsx:

  • Renders the "This directory is empty." message when items={[]}. The real FileTreeItemComponent is stubbed to a plain <li> since the test only exercises the empty-state branch (not the list rendering, which has its own coverage via the end-to-end browse flow).

The test stubs useIsMobile and usePathname (the latter to keep the route context stable; the empty-state branch doesn't read either, but the wrapping SidebarProvider does for the resize listener). The other heavy hooks the panel uses are pulled in via the import path but not exercised by the empty-state branch.

1/1 test pass; full suite 998/998 (the 7 pre-existing OTel-setup failures in ee/askmcp/... and ee/permissionSyncStatus/... are unchanged by this PR).

Backward compatibility

Pure UI change. The data layer is unchanged — same API responses, same shape, same error codes. Only the rendered text changes for the three empty/error cases. Existing users on non-empty repos see no change.

Risks

Minimal. The empty-state messages don't conflict with any existing copy. The 404 distinction is a small UX win. The "Once a commit lands..." copy is informative without being alarming.

Future work

  • A "Re-sync now" button next to the empty-state message, which would trigger the worker to re-attempt the sync. Out of scope for this PR; the existing POST /api/connections/{id}/sync endpoint could be wired up here, but the empty-state message is the more pressing fix.
  • A "Go to settings" link from the 404 message, which would help the user diagnose a misconfigured connection. Out of scope; the 404 copy is enough for now.

Note

Low Risk
Browse UI copy and conditional rendering only; APIs and data shapes are unchanged.

Overview
Improves browse file-tree UX when folder data is missing or empty, instead of a blank panel or a single generic error.

TreePreviewPanel now shows "Repository not found." when getRepoInfoByName returns NOT_FOUND; other service errors still use "Error loading tree preview".

TreePreviewPanelClient treats an empty folder list at the repo root (path === '') as a dedicated full-panel state: "This repository is empty." plus guidance that files appear after a commit on the default branch (no path header).

PureTreePreviewPanel shows "This path has no contents in this revision." when items is empty (sub-path tree view). The copy is deliberately vague because empty dirs and missing paths both look like [] from git ls-tree.

Vitest coverage was added for the empty-root and non-404 error paths on the client, and for the pure panel empty list. CHANGELOG documents the fix (#1530).

Reviewed by Cursor Bugbot for commit 15550f2. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Added clearer empty-state messages for empty repositories and directories.
    • Added a dedicated “Repository not found.” message when a repository cannot be located.
    • Empty or unavailable paths now display an appropriate no-contents message.
    • Preserved existing error messaging for other loading failures.
  • Tests

    • Added coverage verifying empty repository and directory messages.
    • Added coverage for repository-not-found and other tree preview error states.

The browse file-tree panel previously rendered a blank scroll area
when the folder contents were empty (e.g. for a freshly-created,
uncommitted repository) and the generic "Error loading tree preview"
text for service errors — including 404s from a typo in the repo
name. Both are unhelpful.

Three changes:

- `pureTreePreviewPanel.tsx`: render a centered "This directory is
  empty." message when `items.length === 0`. The same component
  covers both the sub-directory case (path != '') and the repo-root
  case (path == ''), because a repo is just a directory at the root.

- `treePreviewPanelClient.tsx`: when the folder-contents response is
  `[]` AND `path === ''`, render a more emphatic "This repository
  is empty." message (no path header, no separator) that takes the
  full panel. The sub-directory case still falls through to
  PureTreePreviewPanel with the "directory" copy. This avoids
  showing a path header for a non-existent root and matches the
  user's intent of distinguishing "no files in this repo" from
  "no files in this sub-directory".

- `treePreviewPanel.tsx`: distinguish 404 from other service errors
  on `getRepoInfoByName`. A 404 means the user hit a typo in a repo
  name (or a config that's no longer indexed) and now shows
  "Repository not found." instead of the generic error text.
  Other status codes keep the existing "Error loading tree preview".

Fixes sourcebot-dev#1530 (and addresses the user-reported screenshots in sourcebot-dev#821).
Adds `pureTreePreviewPanel.test.tsx` with one vitest case asserting
that the component renders the "This directory is empty." message
when `items={[]}`. The real FileTreeItemComponent is stubbed to a
plain `<li>` since the test only exercises the empty-state branch
(not the list rendering, which has its own coverage via the
end-to-end browse flow).

Plus a one-line CHANGELOG entry under [Unreleased] -> Fixed.

Refs sourcebot-dev#1530.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The browse tree preview now shows dedicated messages for empty repositories, empty paths, and missing repositories. Tests cover empty and error states, and the changelog records the updated behavior.

Changes

Tree preview state handling

Layer / File(s) Summary
Empty content rendering
packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanelClient.tsx, packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/pureTreePreviewPanel.tsx, packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanelClient.test.tsx, packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/pureTreePreviewPanel.test.tsx
Root paths with no items show “This repository is empty.” Non-root paths show “This path has no contents in this revision.” Non-empty paths keep the existing file tree.
Repository error messaging
packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanel.tsx, packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanelClient.test.tsx, CHANGELOG.md
NOT_FOUND repository errors show “Repository not found.” Other errors keep “Error loading tree preview.” The changelog records the updated messages.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TreePreviewPanel
  participant TreePreviewPanelClient
  participant PureTreePreviewPanel
  participant FileTree
  TreePreviewPanel->>TreePreviewPanelClient: Render repository tree preview
  TreePreviewPanelClient->>TreePreviewPanelClient: Check folder contents and path
  alt Root path with no items
    TreePreviewPanelClient-->>TreePreviewPanelClient: Render "This repository is empty."
  else Non-root path with no items
    TreePreviewPanelClient->>PureTreePreviewPanel: Pass empty items
    PureTreePreviewPanel-->>TreePreviewPanelClient: Render empty-path message
  else Non-empty path
    TreePreviewPanelClient->>PureTreePreviewPanel: Pass file tree items
    PureTreePreviewPanel->>FileTree: Render items
  end
  alt Repository lookup returns NOT_FOUND
    TreePreviewPanel-->>TreePreviewPanel: Render "Repository not found."
  end
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements the required empty-root, non-root no-content, 404, and non-404 error states with tests and no API or schema changes [#1530].
Out of Scope Changes check ✅ Passed All changes support the linked issue through UI updates, tests, and a related changelog entry; no unrelated code changes are present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding empty-state messages to the web browse file-tree panel.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/pureTreePreviewPanel.test.tsx (1)

28-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add tests for the other new branches.

This test exercises only PureTreePreviewPanel. It does not detect regressions in the root branch that omits PathHeader and Separator, or in the NOT_FOUND branch that renders Repository not found.. Add focused tests for the root empty response, NOT_FOUND, and non-404 service errors.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/web/src/app/`(app)/browse/[...path]/components/treePreviewPanel/pureTreePreviewPanel.test.tsx
around lines 28 - 39, Add focused tests covering the remaining empty-state
branches in the relevant tree preview panel test suite: verify the root empty
response omits PathHeader and Separator, the NOT_FOUND response renders
“Repository not found.”, and a non-404 service error follows its expected error
behavior. Reuse the existing render/wrap helpers and assertions without changing
the current directory-empty test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@packages/web/src/app/`(app)/browse/[...path]/components/treePreviewPanel/pureTreePreviewPanel.test.tsx:
- Around line 28-39: Add focused tests covering the remaining empty-state
branches in the relevant tree preview panel test suite: verify the root empty
response omits PathHeader and Separator, the NOT_FOUND response renders
“Repository not found.”, and a non-404 service error follows its expected error
behavior. Reuse the existing render/wrap helpers and assertions without changing
the current directory-empty test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cea463fb-85ac-4dae-bc40-d9a8ac6d69a5

📥 Commits

Reviewing files that changed from the base of the PR and between 39bf1a0 and b176c63.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/pureTreePreviewPanel.test.tsx
  • packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/pureTreePreviewPanel.tsx
  • packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanel.tsx
  • packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanelClient.tsx

Bugbot finding on PR sourcebot-dev#1531: the previous copy "This directory is
empty." was misleading because `git ls-tree` returns empty output
for both an empty directory AND a path that doesn't exist in the
tree (typo, deleted, etc.). A user navigating to a non-existent
path would be told the directory is empty when in fact the path was
never found.

Switch to "This path has no contents in this revision." which is
intentionally ambiguous — we can't tell the cases apart at this
layer. The user can verify the path by looking at the repo on the
code host.

The root-path case ("This repository is empty.") is unchanged: a
path of `''` is unambiguously the repo root, so the stronger
"empty repo" copy is still accurate.

Updated the test and the CHANGELOG entry to match the new copy.

Refs sourcebot-dev#1531.
@Harsh23Kashyap

Copy link
Copy Markdown
Author

Bugbot finding addressed in 43f29491:

The previous copy "This directory is empty." was misleading because git ls-tree returns empty output for both an empty directory AND a path that doesn't exist in the tree. A user navigating to a non-existent path would have been told the directory is empty when the path was never found.

Switched to "This path has no contents in this revision." which is intentionally ambiguous — we can't tell the cases apart at this layer. The user can verify the path by looking at the repo on the code host.

The root-path case ("This repository is empty.") is unchanged: a path of '' is unambiguously the repo root, so the stronger copy is still accurate there.

Test + CHANGELOG updated to match the new copy. 1/1 treePreview test passes; full suite 998/998.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 43f2949. Configure here.

<p className="text-xs">
Once a commit lands on the default branch, its files will appear here.
</p>
</div>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Root empty state ignores active revision

Medium Severity

The new root empty-state UI runs whenever folderContentsResponse is [] and path === '', but the fetch uses the browse URL’s revisionName (or HEAD). An empty tree at that ref still shows “This repository is empty.” and copy about the default branch, even when the repo has files on other refs or the user is viewing a non-default revision.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 43f2949. Configure here.

…viewPanelClient

CodeRabbit nitpick on PR sourcebot-dev#1531: the original test only covered
PureTreePreviewPanel (the directory-empty case). Add focused tests
for the two other new branches in treePreviewPanelClient:

- Renders the "This repository is empty." message at the root path
  when the folder-contents response is `[]` AND `path === ''`.
  Asserts that the PathHeader and Separator are NOT rendered (the
  root empty-state takes the full panel).
- Renders the "Error loading tree preview" message on a non-404
  service error. The folder-contents client returns the service
  error object for any non-NOT_FOUND error, and the component
  keeps the existing copy for that case.

The third new branch (NOT_FOUND in treePreviewPanel.tsx) is in a
server component that imports the prisma client at module load —
testing it would require mocking prisma and the `getRepoInfoByName`
action, which is heavy infrastructure for a one-line branch. The
NOT_FOUND case is covered by the existing pattern in the rest of
the browse UI and is the same message that's used for "repo not
found" elsewhere.

3/3 treePreview tests pass; full suite 999/999 (1 new test since
the 998 baseline).

Refs sourcebot-dev#1531.
@Harsh23Kashyap

Copy link
Copy Markdown
Author

CodeRabbit nitpick addressed in 15550f2e:

Added two more vitest cases covering the remaining new branches in treePreviewPanelClient.tsx:

  • Root empty path (path === '', response []): renders "This repository is empty." with no PathHeader or Separator. The full panel takes the root empty-state, distinct from the sub-path directory empty-state.
  • Non-404 service error (folder-contents returns a non-NOT_FOUND ServiceError): renders the existing "Error loading tree preview" copy.

Skipped: the NOT_FOUND branch in treePreviewPanel.tsx is a server component that imports the prisma client at module load. Testing it would require mocking prisma and the getRepoInfoByName action, which is heavy infrastructure for a one-line branch. The NOT_FOUND case is covered by the existing pattern in the rest of the browse UI and is the same message that's used for "repo not found" elsewhere.

3/3 treePreview tests pass; full suite 999/999.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Show a 'This repository is empty' message in the browse file tree when folder contents is empty

1 participant