Skip to content

desktop: file links in messages 404 when referenced by basename outside the session root #50876

Closed

Description

@ndckk167

Summary

Clicking a file link in a session message shows a load failure for files that are not
at the session directory root. References written as bare filenames (for example
cleaned.csv) are resolved only against the session directory, so files that live in a
subdirectory of the project always return 404, and the UI shows only a generic error.

Environment

  • opencode version: 2.0.12 (desktop app, .deb install at /opt/OpenCode)
  • OS: Linux 6.17.0-14-generic, Ubuntu 24.04.4 LTS, x86_64, Wayland (GNOME)
  • Terminal: N/A (Electron desktop app)
  • Shell: /usr/bin/zsh
  • Install/channel: latest; update to 2.0.15 downloaded and staged
  • Active plugins: none found in config

Reproduction

  1. In a project session (session directory = project root), have the agent write outputs
    into a subdirectory, for example procrastination_analysis/REPORT.md,
    procrastination_analysis/cleaned.csv, and procrastination_analysis/figs/.
  2. The assistant answer references them by bare name: cleaned.csv, REPORT.md, figs.
  3. Click one of those links in the desktop app.

Expected Behavior

The file opens. The app should resolve the file's real location (or at least show the
resolved path in the error). A directory reference should open a listing.

Actual Behavior

The request returns 404 and the UI only reports a generic load failure. Server log:

GET /api/fs/read/cleaned.csv                          404
GET /api/fs/read/REPORT.md                            404
GET /api/fs/read/figs                                 404
GET /api/fs/read/procrastination_survey_dataset.csv   404

Additional Context

/api/fs/read only resolves a path relative to the requested location, so the same file
succeeds when the correct relative path is used. Running the server directly:

GET /api/fs/read/cleaned.csv?location[directory]=<project root>                          -> 404
GET /api/fs/read/procrastination_analysis/cleaned.csv?location[directory]=<project root> -> 200
GET /api/fs/read/procrastination_survey_dataset.csv?location[directory]=$HOME            -> 404
GET /api/fs/read/下载/procrastination_survey_dataset.csv  (default location = $HOME)     -> 200

Notes:

  • /api/fs/read cannot serve a directory at all (figs returns 404 even though it exists).
  • A file outside the project (for example in ~/下载) referenced by bare filename also
    404s, because the default location is $HOME.
  • Reproducible consistently, not intermittent.
  • The response body for these 404s is a FileNotFoundError with the unresolved path,
    but the desktop UI does not surface it.

Suggested improvements:

  • Fall back to resolving a bare filename under the session root (and under its subdirectories).
  • Show the resolved path in the error instead of a generic load failure.
  • Let directory references open the file tree / listing instead of 404ing.

Activity

  1. paoValle commented on Oct 6, 2026

    @paoValle

    I checked the server side on dev (3f393d7), and the behaviour you are hitting is what the endpoint is specified to do:

    • packages/protocol/src/groups/fs.ts:22 — GET /api/fs/read/*, documented as "Serve one file relative to the requested location".
    • packages/server/src/handlers/fs.ts:12 — the handler takes everything after /api/fs/read/ (pathname.slice(13)), wraps it in RelativePath.make() and passes it straight to the filesystem service. There is no basename lookup, no fallback and no search, so cleaned.csv is resolved against the session directory and nothing else. The 404 comes from the filesystem service, which is why the UI has no resolved path to show you.
    • RelativePath is validated as relative to the location, so the server cannot do better than the string it is handed: the resolution has to happen where the link text is turned into a URL.

    One thing worth a retest on a current build before someone spends time on the server: in dev I cannot find any caller of /api/fs/read (rg -n '\bfs\.read\b' packages/*/src matches only the protocol definition, the server handler and packages/client/src/contract.ts:53, which omits it from the typed client). Your log is from 2.0.12, so if the desktop has since moved file links onto another route the shape may have changed. If it still calls this endpoint, the fix belongs on the client side — resolve the basename against the session directory (or, failing that, show the path that was requested in the error) — because the endpoint has no way to know which cleaned.csv you meant.

  2. neriousy commented on Oct 20, 2026

    @neriousy
    Member

    Thanks for the report! In 2.0.27, file links now search the workspace for matching filenames, opening a unique match or offering a picker when several files match instead of assuming the file is at the session root. Update with opencode upgrade or npm i -g @opencode/cli@latest (desktop: update the app). Please comment or reopen if this still happens on that version.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions