Workspace Files pane silently truncates directory listings at 200 entries — directories with more items are silently incomplete
#6,645 opened on Jul 31, 2026
Repository metrics
- Stars
- (17,368 stars)
- PR merge metrics
- (Avg merge 14h 31m) (314 merged PRs in 30d)
Description
Bug Description
When opening a directory in the Workspace → Files pane that contains more than 200 entries, the listing is silently truncated at exactly 200 entries. Items past the 200th are not rendered, and there is no indication to the user (no "show more" link, no count badge, no warning toast).
Repro path on this installation: ~/.hermes/profiles/<profile>/skills/cybersecurity/ contains 817 sub-folders. The pane only renders the first 200 in alphabetical order — projects (alphabetically a late entry) is the last one shown, with no indication that anything is missing. Sorting is also affected: items 201–817 are dropped regardless of where they fall alphabetically.
Steps to Reproduce
- Open the WebUI and connect to a session whose workspace contains a directory with >200 direct children. (Repro path: a Hermes profile with the Anthropic Cybersecurity Skills installed —
~/.hermes/profiles/<profile>/skills/cybersecurity/.) - Switch the right-hand pane to the Files tab.
- Drill down:
skills/→cybersecurity/→ expand. - Actual: only exact 200 entries render.
projects(or any alphabetically late item) appears as the last row, with no indication that anything is missing. - Expected: the entire listing is shown, or the listing is paginated/virtualized with a visible "showing 200 of 817 — load more" affordance. Silent truncation is unacceptable.
Expected Behavior
- Listing renders completely, or
- is virtualized/paginated with an explicit and discoverable affordance when truncation is applied.
Actual Behavior
api/workspace.py::list_dir(workspace, rel='.') stops appending entries as soon as len(entries) >= 200 and breaks out of the loop, in both code paths. The HTTP response contains only the first 200 entries with no total, has_more or truncated flag, so neither the server nor the client signals that more items exist.
Root Cause (code reference)
File: api/workspace.py, function list_dir(workspace, rel='.') (around line 1276). Two branches both enforce a hard cap of 200:
# Linux / dir_fd path (around line 1427)
_process(name, is_symlink, raw_link, lst, reachable)
if len(entries) >= 200:
break
…
# Portability fallback for Windows / no dir_fd (around line 1470)
_process(name, is_symlink, raw_link, lst, reachable)
if len(entries) >= 200:
break
return entries
The early break is not paired with any has_more / total / truncated flag in the returned payload, so the client cannot know the listing was cut off.
This is consistent with the pattern fixed in #6141 (size-guard cron/skill file reads (bounded, truncated flag)) — same idea, applied to directory listings instead of file bodies.
Environment
- Repo:
nesquena/hermes-webui(master branch) - Working tree at
/home/hermes/hermes-webui - The directory being listed: a Hermes profile skill bundle (~817 direct children in one folder)
- API endpoint:
list_dir(wrapped by the standard managed-files routes)
Suggested Fix (sketch, not a PR)
Either approach works:
- Pagination / virtual list: keep
len(entries) >= 200as a soft hint, return{entries, has_more: true, total: <full count>}and let the client render a "load more" button or virtual-scroll. - Drop the cap server-side, stream entries in pages, render lazily on the client.
- Minimum: pair the existing cap with
has_more=Trueand an explicit UI affordance, so users at least see the truncation.
Impact
Any Hermes user who installs a large skill bundle (e.g. Anthropic's Cybersecurity Skills Repo, which ships 800+ skills) hits this immediately and has no way to know the rest exist through the UI. They must rely on the terminal to confirm the missing items.
Filed by: @stadtschamane