Files
hermes-agent/tests/hermes_cli
Austin Pickett 1ca192bc1b fix(dashboard): don't 500 file listings on dangling symlinks or vanished entries
The dashboard file browser's listing route built entries via a bare
comprehension over os.scandir, calling _managed_file_entry() per entry.
That helper raises HTTP 500 ("Could not stat path") on any OSError from
resolved.stat(), so a single dangling symlink (or an entry removed
between readdir and stat) aborted the whole directory listing with a 500
— e.g. a broken ~/.claude link or Steam's recreated linux32/steam made
the entire Files page unusable (#47154).

Whole-class fix, consolidated from the open contributor PRs:

- _managed_file_entry() classifies a symlink whose target is definitively
  missing (FileNotFoundError) before the resolved-target boundary check
  and returns a `broken_link: true` placeholder entry instead of 500ing.
  The placeholder is only emitted for entries inside the managed root
  even when the missing target resolves outside it. Permission and other
  OSErrors still surface as 403/500 as before.
- Symlink stat results are captured in one snapshot (no second stat), so
  a target disappearing mid-listing cannot flip a result into a 500.
- New skip_missing flag lets the listing scan skip an entry that
  vanished between readdir and stat (returns None); the write-result
  caller stays strict.
- The listing loop appends placeholders and skips vanished entries, so
  one dead entry never loses its siblings. The sibling fs_list route
  already tolerated ENOENT; /api/files now agrees.

Reading/downloading a broken link directly still returns 404; 403
boundary and sensitive-path behavior are unchanged.

Fixes #47154

Co-authored-by: gangpangpang <2564186295@qq.com>
Co-authored-by: ous fifty <ousfifty@gmail.com>

Incorporates work by @Lqg97 (PR 47159; co-contributors qinggangli and Shiqian Ma, commit emails not linked to GitHub accounts).
2026-10-06 12:30:01 -04:00
..