Uh oh!
There was an error while loading. Please reload this page.
fix(server): stop sending the local directory to a remote OpenCode server - #6228
fix(server): stop sending the local directory to a remote OpenCode server#6228CDVolvik wants to merge 1 commit into
Conversation
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Warning Your free Security trial is over. An organization admin can activate Security or dismiss this notice. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 45e3645. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
ApprovabilityVerdict: Would Approve Macroscope's review found this PR approvable — The PR is a focused OpenCode server bug fix with bounded runtime changes and targeted tests, preserving existing managed and loopback behavior. Open High-severity findings still identify risks in external client propagation and loopback classification, which independently require resolution under repository policy. Not approved because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
45e3645 to
f7cdd88CompareCDVolvik
commented
Aug 28, 2026
Fixed the resume gap flagged by Cursor Bugbot @ 45e3645. What was still broken: After creating a remote session without \directory, the adopted session's server-side Linux path (e.g. /var/log) never equalled the local Windows \C:\Users...\ — so \sameDirectory\ returned false, resume took the fork path and re-sent the Windows directory via \session.fork, reproducing the same \Invalid path\ this PR was meant to fix. Fix in f7cdd88:
|
There was a problem hiding this comment.
Effect service conventions review: one finding — the new remote-server branch in OpenCodeAdapter.startSession changes backend behavior but has no focused test. Client-config changes in opencodeRuntime.ts are covered by the new opencodeRuntime.sdkClient.test.ts.
Posted via Macroscope — Effect Service Conventions
| // For a remote server the local directory is meaningless — the | ||
| // client no longer sends it (#3094) and the adopted session's | ||
| // directory is a Linux path that will never equal the Windows | ||
| // one. Skip the cwd check and the fork entirely in that case | ||
| // so we don't reintroduce the Invalid path failure this PR fixes. | ||
| const isRemote = server.external && !isLoopbackBaseUrl(server.url); |
There was a problem hiding this comment.
This changes resume behavior for a remote server (skip the cwd comparison, never fork), but nothing exercises it: the existing suite configures serverUrl: "http://127.0.0.1:9999", which is loopback, so isRemote is always false and the new branch is never taken. Since this is a backend behavior change, consider adding a focused case in OpenCodeAdapter.test.ts with a non-loopback serverUrl (the runtime mock already returns external: Boolean(serverUrl)), asserting the adopted session is reused with forkCalls empty even when its directory differs.
Posted via Macroscope — Effect Service Conventions
| normalized === "localhost" || | ||
| normalized === "::1" || | ||
| normalized === "0.0.0.0" || | ||
| normalized.startsWith("127.") |
There was a problem hiding this comment.
🟠 Highprovider/opencodeRuntime.ts:209
isLoopbackBaseUrl misclassifies valid local endpoints such as localhost., name.localhost, and IPv4-mapped loopback [::ffff:127.0.0.1] as remote, so buildOpenCodeSdkClientConfig omits directory for them. It also classifies remote DNS names such as 127.example.com as loopback because of the textual 127. prefix, causing the local directory to be sent to external servers. Use proper hostname/IP parsing to recognize loopback domains and IPv4/IPv6 loopback addresses without treating arbitrary 127.* DNS names as literals.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/opencodeRuntime.ts around line 209:
`isLoopbackBaseUrl` misclassifies valid local endpoints such as `localhost.`, `name.localhost`, and IPv4-mapped loopback `[::ffff:127.0.0.1]` as remote, so `buildOpenCodeSdkClientConfig` omits `directory` for them. It also classifies remote DNS names such as `127.example.com` as loopback because of the textual `127.` prefix, causing the local directory to be sent to external servers. Use proper hostname/IP parsing to recognize loopback domains and IPv4/IPv6 loopback addresses without treating arbitrary `127.*` DNS names as literals.
f7cdd88 to
59b7548Compare…rver Connecting to an OpenCode server by URL from Windows failed to load models, with the server reporting Invalid path /var/log/C:\Users\.... The client is built with the local working directory and forwards it to whichever server is on the other end, so a Windows path reached a Linux host and was joined onto its own. The message comes from OpenCode itself; what we contribute is a path that cannot mean anything there. Only skip the directory when the server is externally configured AND its URL is not loopback. External is not the same thing as remote: running OpenCode locally and pointing the setting at http://localhost:4096 is also external, and there the directory is correct and worth sending. Dropping it for those users would trade a visible failure for a silent one, so localhost, 127.0.0.0/8, ::1 and 0.0.0.0 all keep it, as does a base URL that cannot be parsed. The client config moves into a pure buildOpenCodeSdkClientConfig so the decision is testable on its own, alongside the other exported helpers in this module. Callers pass the externality they already know: the two adapter paths forward server.external, which OpenCodeAdapter already branches on for the authorization header, and the text-generation path uses the configured serverUrl it already tests for the same purpose. Follow-up: resume was still broken. After creating a session without a directory, the adopted session's server-side directory never matched the local Windows path, so the fork path reintroduced the same Invalid path failure. For remote (external non-loopback) sessions the cwd check and fork are now skipped entirely — any adopted session is reused in place. isLoopbackBaseUrl is exported for the adapter to share the same heuristic. Three of the five new tests cover the cases that must NOT change, and they pass against the previous always-send behaviour as well, so they pin the localhost case rather than the fix. Fixespingdotgg#3094
59b7548 to
28715a9Compare| : {}), | ||
| throwOnError: true, | ||
| }); | ||
| createOpencodeClient(buildOpenCodeSdkClientConfig(input)); |
There was a problem hiding this comment.
🟠 Highprovider/opencodeRuntime.ts:638
createOpenCodeSdkClient sends directory to external OpenCode servers because the external-server path in connectToOpenCodeServer does not set external: true. As a result, buildOpenCodeSdkClientConfig keeps sendDirectory true and remote servers receive the caller's local path, which can cause invalid-path errors. Pass external: true when creating the client for the external-server branch.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/opencodeRuntime.ts around line 638:
`createOpenCodeSdkClient` sends `directory` to external OpenCode servers because the external-server path in `connectToOpenCodeServer` does not set `external: true`. As a result, `buildOpenCodeSdkClientConfig` keeps `sendDirectory` true and remote servers receive the caller's local path, which can cause invalid-path errors. Pass `external: true` when creating the client for the external-server branch.

What Changed
createOpenCodeSdkClientno longer forwards the localdirectoryto an OpenCode server that is both external and not on loopback. The client config moved into a purebuildOpenCodeSdkClientConfigso the decision is testable on its own, and the three callers pass the externality they already hold.Why
Fixes#3094. All three call sites pass a local path unconditionally, so a Linux OpenCode server joins a Windows path onto its own and produces
Invalid path /var/log/C:\Users\xxx. The error text comes from OpenCode's own bundle; what this repo controls is handing it a path that cannot mean anything on that host.The obvious version of this fix — drop
directorywheneverserver.external— is wrong, which is why the diff is a little larger than one line. Someone running OpenCode locally and pointing t3code athttp://localhost:4096is alsoexternal: true, and there the local directory is correct and useful. Dropping it would move those users to the server's own cwd and trade a loud bug for a quiet one. Solocalhost,127.0.0.0/8,::1,0.0.0.0and an unparseable base URL all keep the directory; a malformed setting cannot quietly change what the server receives.The loopback narrowing is a heuristic and it is the one thing here I would rather you chose than me. If you would prefer an explicit setting, or a different definition of "remote", say which and I will change it.
Tests: 97/97 across the opencode and text-generation suites,
tsgo --noEmitclean. Two new tests fail when the decision is reverted to always-send. Three others pass either way on purpose — they pin the local-external case, which is the regression the naive one-liner would have caused.One honest limit: because
buildOpenCodeSdkClientConfigis new, "fails without the fix" was demonstrated by reverting the decision and keeping the helper. Deleting the helper outright would only prove its own absence.Checklist
Note
Medium Risk
Changes OpenCode connection and session-resume behavior for remote servers; loopback external URLs are explicitly preserved, but misclassified hostnames could still omit or send directory incorrectly.
Overview
Fixes #3094 by stopping the server from forwarding the client’s local
directoryto OpenCode when the target is an external, non-loopback host, which was producing invalid joined paths (e.g. Linux server + Windows cwd).SDK client setup is centralized in
buildOpenCodeSdkClientConfigwithisLoopbackBaseUrl:directoryis omitted only whenexternalis true and the base URL is not localhost/127.x/::1 (unparseable URLs still senddirectoryso misconfiguration does not silently drop it). Adapter, provider inventory, and text-generation paths passexternalintocreateOpenCodeSdkClient.Session resume in
OpenCodeAdaptertreats the same “remote” case as reusable without cwd comparison orsession.fork, so resume no longer forks with a local path when the adopted session’s directory is server-side only. Local/managed behavior is unchanged.Reviewed by Cursor Bugbot for commit 28715a9. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Stop sending local directory to remote OpenCode servers
isLoopbackBaseUrlandbuildOpenCodeSdkClientConfigin opencodeRuntime.ts so the SDK client omits thedirectoryfield for external, non-loopback servers while still sending auth headersstartSessionin OpenCodeAdapter.ts to treat adopted sessions from remote servers as reusable without comparing directories and to skip forking, only callingsession.updateto reassert permissionsexternalflag through all SDK client construction sites: inventory loading in OpenCodeProvider.ts and text generation in OpenCodeTextGeneration.tsMacroscope summarized 28715a9.