attach: @ file mentions use client-local path instead of remote directory #9396

Closed
opened 2026-02-16 18:12:21 -05:00 by yindo · 2 comments
Owner

Originally created by @the3asic on GitHub (Feb 15, 2026).

Originally assigned to: @rekram1-node on GitHub.

Bug

When using opencode attach to connect to a remote OpenCode server, selecting a file via @ mention in the TUI builds a file://... URL using the client machine's process.cwd() (local path), not the remote server's working directory.

This causes the server to resolve the URL on the remote filesystem and try to read a path that only exists on the client (e.g. a macOS path), so the attachment fails / the wrong file is read.

Environment

  • OpenCode CLI: 1.2.4
  • Client: macOS
  • Server: Linux (remote OpenCode server)

Steps to reproduce

  1. Start an OpenCode server on a remote machine (e.g. opencode serve).
  2. On the client machine, run: opencode attach http://<remote-host>:4096 --dir /path/to/project (or attach to a server already running in that project).
  3. In the TUI prompt, type @ and select any file from autocomplete.

Actual

The inserted part uses a file:// URL based on the client's process.cwd() (local path). The server then resolves that URL and tries to read it on the remote filesystem, resulting in file-not-found / incorrect file content.

Expected

@ file mentions during remote attach should resolve against the remote server directory (e.g. the directory returned by path.get() / sync.data.path.directory, or the directory provided via --dir).

Likely cause

packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx currently does:

const fullPath = `${process.cwd()}/${item}`
const urlObj = pathToFileURL(fullPath)

When attached, process.cwd() is client-local.

Suggested fix

Use the remote directory from sync (e.g. sync.data.path.directory, sourced from sdk.client.path.get()) as the base directory for pathToFileURL, with a fallback to process.cwd() for local mode.

Example:

const baseDir = (sync.data.path.directory || process.cwd()).replace(/\/+$/, "")
const fullPath = item.startsWith("/") ? item : `${baseDir}/${item}`
const urlObj = pathToFileURL(fullPath)
Originally created by @the3asic on GitHub (Feb 15, 2026). Originally assigned to: @rekram1-node on GitHub. ### Bug When using `opencode attach` to connect to a remote OpenCode server, selecting a file via `@` mention in the TUI builds a `file://...` URL using the *client* machine's `process.cwd()` (local path), not the remote server's working directory. This causes the server to resolve the URL on the remote filesystem and try to read a path that only exists on the client (e.g. a macOS path), so the attachment fails / the wrong file is read. ### Environment - OpenCode CLI: 1.2.4 - Client: macOS - Server: Linux (remote OpenCode server) ### Steps to reproduce 1. Start an OpenCode server on a remote machine (e.g. `opencode serve`). 2. On the client machine, run: `opencode attach http://<remote-host>:4096 --dir /path/to/project` (or attach to a server already running in that project). 3. In the TUI prompt, type `@` and select any file from autocomplete. ### Actual The inserted part uses a `file://` URL based on the client's `process.cwd()` (local path). The server then resolves that URL and tries to read it on the remote filesystem, resulting in file-not-found / incorrect file content. ### Expected `@` file mentions during remote attach should resolve against the remote server directory (e.g. the directory returned by `path.get()` / `sync.data.path.directory`, or the directory provided via `--dir`). ### Likely cause `packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx` currently does: ```ts const fullPath = `${process.cwd()}/${item}` const urlObj = pathToFileURL(fullPath) ``` When attached, `process.cwd()` is client-local. ### Suggested fix Use the remote directory from sync (e.g. `sync.data.path.directory`, sourced from `sdk.client.path.get()`) as the base directory for `pathToFileURL`, with a fallback to `process.cwd()` for local mode. Example: ```ts const baseDir = (sync.data.path.directory || process.cwd()).replace(/\/+$/, "") const fullPath = item.startsWith("/") ? item : `${baseDir}/${item}` const urlObj = pathToFileURL(fullPath) ```
yindo added the opentui label 2026-02-16 18:12:21 -05:00
yindo closed this issue 2026-02-16 18:12:21 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Feb 15, 2026):

This issue appears to be related to several existing reports about path resolution when attaching to remote servers. Please check these related issues to see if they address your use case or if there are any workarounds:

  • #4967: opencode attach file path duplicates causing ENOENT
  • #5380: TUI referencing local directory when using attach --dir to connect to a remote server
  • #4686: TUI sends absolute local paths causing ENOENT on server side
  • #11896: attach --dir with remote server is broken

These issues all involve client-local paths being incorrectly used instead of remote server paths in various attachment scenarios.

@github-actions[bot] commented on GitHub (Feb 15, 2026): This issue appears to be related to several existing reports about path resolution when attaching to remote servers. Please check these related issues to see if they address your use case or if there are any workarounds: - #4967: `opencode attach` file path duplicates causing ENOENT - #5380: TUI referencing local directory when using `attach --dir` to connect to a remote server - #4686: TUI sends absolute local paths causing ENOENT on server side - #11896: `attach --dir` with remote server is broken These issues all involve client-local paths being incorrectly used instead of remote server paths in various attachment scenarios.
Author
Owner

@OpeOginni commented on GitHub (Feb 15, 2026):

Yeah Im able to reproduce, and your suggested solution works too.

@OpeOginni commented on GitHub (Feb 15, 2026): Yeah Im able to reproduce, and your suggested solution works too.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#9396