From da4a6570f59df1391ad268e13a76494453fe150a Mon Sep 17 00:00:00 2001 From: James Murdza Date: Sun, 2 Aug 2026 12:55:56 +0700 Subject: [PATCH] fix(server): don't forward host directory to remote workspace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When proxying a request to a remote workspace, workspaceProxyURL kept the `directory` query param — the *host's* working directory (e.g. a Windows path `F:\proj`). The Linux sandbox then `path.resolve`d it against its own cwd, yielding a bogus dir like `/home/daytona/workspace/repo/F:\proj` that doesn't exist. Sessions were created against that path, and the first prompt crashed in SystemPrompt.environment (realPath -> ENOENT), which the prompt handler converts to a defect -> opaque 500 -> 'Failed to send prompt' toast. Strip the `directory` param when forwarding so the remote falls back to its own project root, mirroring ProxyUtil.headers already stripping the `x-opencode-directory` header. Co-Authored-By: Claude Opus 4.8 --- packages/opencode/src/server/shared/workspace-routing.ts | 7 +++++++ packages/opencode/test/server/workspace-routing.test.ts | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/packages/opencode/src/server/shared/workspace-routing.ts b/packages/opencode/src/server/shared/workspace-routing.ts index 0edfb2b30542..de4dc672031e 100644 --- a/packages/opencode/src/server/shared/workspace-routing.ts +++ b/packages/opencode/src/server/shared/workspace-routing.ts @@ -34,5 +34,12 @@ export function workspaceProxyURL(target: string | URL, requestURL: URL) { proxyURL.search = requestURL.search proxyURL.hash = requestURL.hash proxyURL.searchParams.delete("workspace") + // The `directory` param is the *host's* working directory (e.g. a Windows + // path like `F:\proj`). It is meaningless — and dangerous — on the remote: + // the sandbox would `path.resolve` it against its own cwd, producing a bogus + // path like `/home/daytona/workspace/repo/F:\proj` that does not exist and + // crashes prompt handling. Drop it so the remote falls back to its own + // project root. This mirrors ProxyUtil.headers stripping `x-opencode-directory`. + proxyURL.searchParams.delete("directory") return proxyURL } diff --git a/packages/opencode/test/server/workspace-routing.test.ts b/packages/opencode/test/server/workspace-routing.test.ts index 9ae0f3e632c4..29c22038c3b6 100644 --- a/packages/opencode/test/server/workspace-routing.test.ts +++ b/packages/opencode/test/server/workspace-routing.test.ts @@ -80,6 +80,13 @@ describe("workspaceProxyURL", () => { expect(result.searchParams.get("keep")).toBe("yes") }) + test("strips the host directory param so the remote resolves its own root", () => { + const url = new URL("http://localhost/session/abc?directory=F%3A%5Cproj&keep=yes") + const result = workspaceProxyURL("http://remote:8080/base", url) + expect(result.searchParams.get("directory")).toBeNull() + expect(result.searchParams.get("keep")).toBe("yes") + }) + test("preserves hash from request", () => { const url = new URL("http://localhost/page#section") const result = workspaceProxyURL("http://remote:8080", url)