Repository navigation
bug(web): chat-message file link to ~/subdir/file.md drops path segment, ENOENT + spurious git-diff error #2059
Description
Summary
Clicking a ~/-prefixed file link in a session chat message produces a backend file-read error, and the directory component of the path is silently dropped — not just a dead SPA link (the #1452 symptom), but an actual (wrong) stat attempt on the backend.
What version of HAPI is running?
- HAPI:
0.30.7 - Platform: macOS
What issue are you seeing?
A chat message (sent via ping_peer) referenced a file as plain prose: ~/hapi-team/ORG-STRUCTURE.md. The session's cwd is /Users/clawdbot (the bare home directory, not a project checkout, and not a git repository).
Clicking the rendered link in the Hub web UI produces two errors:
Failed to read file: ENOENT: no such file or directory, stat '/Users/clawdbot/ORG-STRUCTURE.md'
Diff unavailable: Not a git repository
Two distinct problems in one symptom:
- The
hapi-team/path segment is dropped entirely. The real file is at/Users/clawdbot/hapi-team/ORG-STRUCTURE.md(i.e.~resolved correctly to the home directory, but only the basenameORG-STRUCTURE.mdwas kept — the intermediate directory component disappeared). This is not what#1452's table describes for~/coding/…/foo.md(which predicted a dead SPA nav, not a backendstaton a mangled path) — this looks like a different, possibly newer code path that does attempt backend resolution for~/-prefixed links, but resolves the path incorrectly. - "Diff unavailable: Not a git repository" fires unconditionally as a second error, even though the file link was a plain file reference with no diff/git context implied. The session's
cwd(/Users/clawdbot) happens not to be a git repo, which suggests the file-link handler always attempts a git-relative diff lookup regardless of whether the user asked for one.
Steps to reproduce
- Start (or use) a session whose
cwdis not a git repository (e.g. a bare home directory session). - Have the agent send a chat message containing a bare-prose or markdown-link reference to a file under a subdirectory of
$HOME, e.g.~/some-subdir/file.md, wheresome-subdiris not the session's cwd. - Open the session in the Hub web UI and click the rendered file link.
- Observe:
Failed to read file: ENOENT: ... stat '$HOME/file.md'(the subdirectory segment is missing) andDiff unavailable: Not a git repository.
Expected behavior
- A
~/-prefixed path should resolve against the full path given (home directory + all intermediate segments), not just home directory + basename. - The diff lookup should not be attempted (or should fail silently/not display an error) for a plain file-link click that never requested a diff view, especially when the session
cwdis known not to be a git repository.
Related
- web: relative markdown hrefs still paint clickable SPA dead-ends (fail-open after #1142) #1452 (closed, PR fix(web): fail-closed scheme-less markdown file links #1519) — documented
~/coding/…/foo.mdas a rejected/dead-link case for the chat message renderer specifically; this report shows a different failure mode (backend ENOENT on a mangled path) for the same class of href, suggesting either a partial regression or a previously-unhandled sub-case. - fix(web): resolve relative Markdown assets and support HTTPS images in file preview #1870 / fix(web): resolve relative Markdown assets and support HTTPS images in file preview (follow-up to #1870) #1917 (open) — same general "relative/home-relative path resolution in file preview" problem family, but scoped to the standalone Markdown file-preview renderer rather than the chat message renderer; fix(web): resolve relative Markdown assets and support HTTPS images in file preview (follow-up to #1870) #1917's own text notes "the chat message renderer has separate support for some file links" — this report is specifically about that separate chat-message code path.
AI disclosure: this report was prepared by an AI agent (Claude, via HAPI) investigating an internally-reported UI bug, cross-checked against the existing issue tracker before filing per the operator's own process standard (check community/docs before assuming something is novel).
Activity
github-actions commentedon Oct 18, 2026
The extra Git error is explained by the current file viewer: opening a file requests both its content and a Git diff, without requiring the user to select a diff view. A returned diff error is displayed independently of the file-read result.
The missing
hapi-team/segment remains unconfirmed. In a direct check against this checkout, an explicit Markdown link targeting~/hapi-team/ORG-STRUCTURE.md, with workspace/Users/clawdbot, resolves to/Users/clawdbot/hapi-team/ORG-STRUCTURE.md. The same path in bare prose or inline code stays unlinked in the file-path plugin. I did not find a basename-only conversion in the traced link → file-read path, so the reportedstaterror alone does not establish that tilde expansion succeeded.Relevant code:
web/src/routes/sessions/file.tsx:251— enables the diff request alongside the file read;web/src/routes/sessions/file.tsx:473displays a returned diff error.web/src/lib/markdown-href-policy.ts:92— tilde expansion retains the entire suffix;web/src/lib/markdown-href-policy.ts:213applies workspace containment before opening the file.web/src/components/assistant-ui/markdown-text.tsx:534— passes the file path into the viewer's URL, encoded as Base64.cli/src/modules/common/handlers/files.ts:46— resolves the supplied path against the session working directory, then callsstatand reads the file.For this session, an explicit relative link such as
[ORG-STRUCTURE.md](hapi-team/ORG-STRUCTURE.md)is supported by the current link transformer (web/src/lib/remark-file-path-links.ts:214). It still uses the same viewer, so the diff warning remains a separate issue.Need more info:
pathquery parameter sent to/api/sessions/…/filein browser Network tools. Session IDs and hostnames can be redacted.HAPI Bot