Chat file links fail with Not allowed to open path outside $HOME
- Dominant language
- TypeScript
- Stars
- 909
- Forks
- 116
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 156
Description
### Before filing
- [x] I searched [open and closed issues](https://github.com/block/berd/issues?q=is%3Aissue) for duplicates.
- [x] I reproduced this on the [latest release](https://github.com/block/berd/releases).
- [x] This is one bug, not several bundled together.
### Closest existing issue
none found. #112 is about adding an in-app file viewer for the Files tray, not about chat markdown/image links being rejected by the opener allowlist.
### What's broken
Clicking a local markdown or image path in chat shows `Not allowed to open path ` whenever the file is outside the current macOS home directory, even when that path is the attached project folder and the file exists and is readable.
### Steps to reproduce
1. Launch Berd 0.6.2 on macOS.
2. Open or create a project whose working directory is outside `$HOME`. The path that failed here was an attached project folder under `/Users/Shared/...`.
3. Confirm the folder is attached as the session cwd (`berdctl folder list` reported that project path as cwd).
4. In that chat, have the agent emit a normal markdown file or image link to a real file inside the attached folder, for example a `[label](/Users/Shared/.../file.png)` or `` link.
5. Click the link in the transcript.
Model/provider does not appear to matter. Reproduced from a Goose chat after the agent had already generated and linked the file. The same toast also appeared for markdown links such as a `.md` file in the same attached project.
### What you expected to happen
Because the file exists, is readable, and sits inside the attached project / session cwd, the click should open it (Finder/Preview or the in-app artifact viewer). Attached project folders should be treated as allowed local paths.
### What actually happened
Berd showed a toast:
`Not allowed to open path /Users/Shared/.../.png`
The file was not opened. `open` from the shell opened the same file immediately, so this is not a macOS permissions or missing-file problem.
The renderer log records the same failure as an unhandled rejection:
`errorName=Error message="Not allowed to open path /Users/Shared/.../ROLE_MAP.md"`
### How often does it happen?
Every time — reliably reproducible
### Berd version
0.6.2
### Operating system
macOS (Apple Silicon)
### Model and provider
n/a for the click itself. Observed in a Goose chat; the same toast happens as soon as the local path is clicked.
### Relevant log output
```text
[2026-08-21][01:39:21][berd_lib::services::diagnostic_log][ERROR] [diagnostic] category=renderer event=unhandled_rejection app_version=0.6.2 platform=macos errorName=Error message="Not allowed to open path /Users/Shared/PROJECTS_shared/LALA/.agents/skills/lala-keyframe-pipeline/references/ROLE_MAP.md" stack="" windowKind=main
```
`/usr/bin/open` on the same machine opens the same path successfully.
### Screenshots, recordings, or other context
Chat link clicks go through `useArtifactLinkHandler` -> `openResolvedPath` -> `@tauri-apps/plugin-opener` `openPath()` (`src/features/chat/hooks/useArtifactLinkHandler.ts`, `src/features/chat/hooks/ArtifactPolicyContext.tsx`). The toast text is the plugin error `Not allowed to open path `.
`src-tauri/capabilities/default.json` on v0.6.2 allows `$HOME/**`, `$TEMP/**`, `/Volumes/**`, `/mnt/**`, `/workspace/**`, `/workspaces/**`, `/opt/**`, `/srv/**`, and `*:/**`. That does not include `/Users/Shared/**` or other attached project roots outside `$HOME`.
The shipped 0.6.2 binary also contains a narrower nearby allowlist of `$HOME/.goose/**`, `/Volumes/**`, `/workspace/**`, `/workspaces/**`, and `$DOWNLOAD`. Either way, an attached project under `/Users/Shared` is rejected.
This is not Full Disk Access / sandbox denial: the file is readable, and `/usr/bin/open` works. The session already has the folder attached as cwd.
Related but separate: the same `/Users/Shared/...` project images also fail inline preview with `asset protocol not configured to allow the path`, because `tauri.conf.json` `assetProtocol.scope` is `$HOME/**/*`, `$TEMP/**/*`, and Berd app-data media caches. I am not bundling that here.
Workaround that works today: open the path from a terminal, or copy/symlink the file into `~/Downloads` / `$HOME`.
Contributor guide
Research direction
Start with src/features/chat/hooks/useArtifactLinkHandler.ts and src/features/chat/hooks/ArtifactPolicyContext.tsx, then inspect src-tauri/capabilities/default.json and the attached-folder handling. Reproduce a chat link to a readable file under /Users/Shared and verify that an attached project path opens while unrelated paths remain protected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, tauri, typescript
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100