Repository navigation
Description
Summary
Per the ACP session/list spec, an empty params object should return "the first page of sessions," and the optional cwd parameter should filter to "sessions with a matching cwd." In practice, opencode's ACP session/list handler does neither: it silently scopes to the git-derived "project" of wherever the agent process was launched, and discards any cwd value you actually pass.
Repro
$ pwd
/path/to/some-git-repo # a git repo opencode has never seen before
$ opencode acp
{"jsonrpc":"2.0","id":1,"method":"session/list","params":{}}
{"jsonrpc":"2.0","id":1,"result":{"sessions":[]}}
$ pwd
/home/someuser # not a git repo
$ opencode acp
{"jsonrpc":"2.0","id":1,"method":"session/list","params":{}}
{"jsonrpc":"2.0","id":1,"result":{"sessions":[ ... dozens of sessions with unrelated cwds,
e.g. various temp directories and other unrelated project paths ... ]}}
Same method, same empty params, wildly different results depending on the literal directory the agent process happens to be started from — and neither result is "all sessions."
Expected (per spec)
"All parameters are optional. A request with an empty
paramsobject returns the first page of sessions."
cwd: "Filter sessions by working directory. Must be an absolute path. Only sessions with a matchingcwdare returned."
Actual / root cause
-
Empty
paramsis not unfiltered.Session.listalways scopes to the current instance's project id, with no way to opt out:// packages/opencode/src/session/session.ts:548-555 const list = Effect.fn("Session.list")(function* (input?: ListInput) { const ctx = yield* InstanceState.context return yield* listByProject(db, { projectID: ctx.project.id, ...input }) })
ctx.project.idcomes fromProjectV2.resolve()(packages/core/src/project.ts:110-122), which walks up from the server's own launch directory looking for a git repo. No repo → everything collapses into the sharedID.globalbucket (explaining why a non-git launch directory returns a grab-bag of unrelated sessions from every prior non-git invocation). A repo found → a brand-new project id scoped to that repo, which starts out empty even though other sessions exist elsewhere. -
cwdis treated as a boolean, not a filter value. Even when the ACP layer forwardsparams.cwd(packages/opencode/src/acp/service.ts:251), the underlying HTTP handler ignores the actual value:// packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts:65 const directory = ctx.query.directory ? yield* InstanceState.directory : undefined
Any truthy
directory/cwdis replaced withInstanceState.directory(the running instance's own directory) before the equality filter runs. Sosession/list { cwd: "/some/other/path" }never actually filters by/some/other/path— it filters by wherever the server itself started.
This looks like the REST endpoint was designed for opencode's own UI/CLI, where a server instance is pinned 1:1 to a workspace and "directory" is really just a "scope to my workspace" toggle — and the ACP bridge is reusing it as if it implemented the protocol's literal cwd filter, which it doesn't.
Suggested fix
- Default (
cwdomitted): return sessions across all known projects/directories, not just the launch instance's project. - When
cwdis provided: filter by exact equality againstSessionTable.directory/cwd, using the client-supplied value — notInstanceState.directory.
Activity
github-actions commentedon Jul 29, 2026
This issue might be a duplicate of existing issues. Please check:
session/listwithoutcwdis scoped to process project — covers the same empty-params scoping problem, with additional references to ACP unstable_listSessions only returns sessions for the current project #18575 and [BUG] Zed ACP registry mode shows stale Recent sessions (unscoped /session) #16137If this is the same underlying issue, consider adding any new information (particularly the
cwdfilter value being discarded, which may not be fully covered in #33036) as a comment there instead.github-actions commentedon Sep 28, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.