Repository navigation
Description
Description
Summary
DELETE /api/session/{sessionID} fails silently (returns success) when the session's stored directory no longer exists on disk. The server actually returns HTTP 500, but the opencode2 api delete CLI masks it as a success (exit 0, empty output), leaving the session intact.
opencode2 v0.0.0-beta-19234
Description
Deleting a session whose directory column points to a path that no longer exists on disk does not delete the session. The server throws an internal FileSystem.realPath error and returns HTTP 500, but the api delete CLI swallows the failure and exits 0 with empty output, so callers (and the api command itself) cannot tell the delete failed. The database row stays behind in both session and session_v2, and the session keeps appearing in GET /api/session.
This is the same FileSystem.realPath ENOENT failure mode that already breaks prompt_async/session.command for stale directories (see #35427, #38013, #38578) — but now it also makes deletion impossible for those affected sessions, with no error surfaced.
Reproduction
# 1. Create a session in a temp directory
mkdir -p /tmp/octest && cd /tmp/octest
# 2. Create a session there via the API
opencode2 api post /api/session --data '{"location":{"directory":"/tmp/octest"}}'
# note the returned session id, e.g. ses_...
# 3. Remove the directory so the session's stored path is stale
cd /tmp && rm -rf /tmp/octest
# 4. Attempt to delete the session — reports success...
opencode2 api delete /api/session/ses_<id>; echo "exit=$?"
# 5. ...but the session is still there
opencode2 api get /api/session/ses_<id>Expected: the delete removes the session regardless of whether its on-disk directory still exists, and a real failure is reported as an error (non-zero exit and/or error output).
Actual:
opencode2 api deleteprints nothing and exits 0 (looks successful).GET /api/session/ses_<id>still returns the full session.- The row remains in the
sessionandsession_v2tables.
Server log evidence
From ~/.local/share/opencode/log/opencode.log during the delete:
role=server http.method=DELETE http.url=/api/session/ses_<id> http.status=500
cause="PlatformError: NotFound: FileSystem.realPath (/tmp/octest)
at FileSystem.realPath ...
Error: ENOENT: no such file or directory, lstat '/tmp/octest'"
(The directory /tmp/octest had been removed beforehand.)
The HTTP 500 is then masked: opencode2 api delete still returns exit code 0 and empty stdout/stderr. Contrast: deleting a session whose directory does exist returns the genuine success (session removed; GET afterwards returns SessionNotFoundError).
Impact
- Users are left with undeletable "ghost" sessions after moving/deleting a project directory (exactly the same stale-directory problem covered by issues such as 500 error on POST /session/{id}/command when session.directory points to a moved/deleted project #35427 / Deleting/Renaming the lastest project fold will make Opencode not working. #38013 / Desktop restores a moved/deleted workspace and leaves its sessions permanently failing with FileSystem.realPath ENOENT #38578 /
opencode -cfails with "Unexpected server error" after project directory is renamed/deleted #40677 / opencode seems to keep old project folder data with no easy way to remove it. #40699). - Because the CLI masks the failure, scripts that rely on exit codes or empty output wrongly report success and the session is silently never cleaned up.
- The only current workaround is deleting the session rows directly from the on-disk SQLite database (
~/.local/share/opencode/opencode.db).
Suggested fix
- In the
DELETE /api/session/{sessionID}handler, do not fail (and do not try torealPath) the session's directory as part of deletion — or wrap the directory resolution so a missing path does not abort the delete (e.g.Effect.catchAll/ guard around theFileSystem.realPathon stale session directories, matching the pattern proposed in fix(opencode): handle stale session.directory gracefully #35479). - Make
opencode2 api <method> <path>surface server HTTP failures with a non-zero exit code and the response body to stderr/stdout, instead of returning success on a 500.
Additional context
- No response data returned on success would normally be a 204; a 500 must never be reported as success by the CLI.
- Deleting the rows directly from the database (both
sessionandsession_v2plus childmessage/part/session_messagerows) is a working workaround while this is unfixed.
Plugins
No response
OpenCode version
opencode2 v0.0.0-beta-19234
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response
Activity