Repository navigation
Session lookup fails with NotFoundError when PTY spawned from non-git directory context #8538
Description
Activity
github-actions commented
on Jan 14, 2026 on Jan 14, 2026 – with GitHub ActionsContributorMore actionsThis issue might be a duplicate of existing issues. Please check:
- Service crashes on missing session file (NotFoundError) #7773: Service crashes on missing session file (NotFoundError) - Similar NotFoundError when accessing session files that don't exist
Feel free to ignore if none of these address your specific case.
Additional Findings from SDK/Server Debugging
I've been debugging this exact issue when using
opencode servewith SDK clients and found additional context that may help.SDK Client Directory Header Gap
The
@opencode-ai/sdkclient only sendsx-opencode-directoryheader whendirectoryis configured at client creation time. Individual API calls don't consistently pass directory context, even when the caller knows the correct directory.Affected operations:
Operation Passes Directory? session.create✅ Yes (query param) session.get❌ No session.prompt❌ No session.messages❌ No Reproduction via
opencode serve- Start
opencode servein project A (e.g.,/home/user/projects/myapp) - Connect via SDK from a different project context (project B)
- Create a session - stored in correct project dir:
~/.local/share/opencode/storage/session/eb6c255.../ses_xxx.json - Subsequent
session.getorsession.messagesfails with NotFoundError:Resource not found: ~/.local/share/opencode/storage/session/global/ses_xxx.json
Suggested Fix Approaches
Option A: Server-side session resolution (preferred)
When looking up a session by ID, resolve the correct project directory:- Maintain a lightweight session-to-projectID index, OR
- Search across project directories if not found in current context, OR
- Store sessions in a flat structure with projectID embedded in filename
Option B: SDK/API enhancement
Allowdirectoryparameter on all session operations (get,prompt,messages), not justcreate. This pushes the burden to callers but would unblock SDK users.I've submitted PR #9474 implementing Option A with caching for performance.
- Start
- added a commit that references this issue
on Jan 19, 2026 Additional confirmation: initializing a git repo does not resolve this.
Context
- Environment: OpenCode Desktop/Web connected to external server at http://127.0.0.1:4096
- Version: v1.1.51
- I initialized a git repository in the directory where I launch OpenCode.
Observation
- Even after
git init, session lookups still resolve undersession/global/...and triggerNotFoundErrorwhen reading by session ID. - This suggests the issue persists beyond the non-git/PTY scenario discussed here when using an external server/Desktop/Web setup.
Reference
- Related sanitized report with details and suggestions: bug: delegate_task fails with NotFoundError when using external OpenCode Server #11342 (comment)
- added 2 commits that reference this issue
on Mar 14, 2026 I encountered a related case that isn't explicitly described in this issue:
- Start opencode in a directory without a Git repository
- Session is created under the global project (as expected)
- During the session, initialize a Git repo (git init + first commit) — in my case, the agent itself created the repo as part of the workflow
- Close OpenCode
- Reopen OpenCode in the same directory — it now detects the Git repo and resolves to a new project ID
- The previous session is not visible in /sessions because it's still associated with the global project
The session data is not lost — it's still in the SQLite database (~/.local/share/opencode/opencode.db) under project_id = 'global'. I was able to recover it by manually updating the project_id and directory fields in the session table.
This seems like a case where OpenCode should either:
- Migrate existing global sessions when a Git repo is detected in the same working directory, or
- At minimum, detect that sessions exist under global for the current directory and surface them in /sessions
This is consistent with the server-side session resolution approach suggested in PR #9474 (Option A).
Environment: OpenCode v1.3.3 on Linux (TUI)
Additional scenario:
git initduring an active sessionI encountered a case where sessions become orphaned after initializing a Git repo during an active session.
Steps to reproduce:
- Start
opencodein a directory without a Git repository (e.g.,~) - A session is created under the
globalproject withdirectoryset to the launch directory (e.g.,/home/simon) - During the session, create a subdirectory and initialize a Git repo (e.g.,
git init+ first commit in~/prog/tewst) — in my case, the agent itself created the repo as part of the workflow - Close OpenCode
- Reopen OpenCode in the new Git repo directory (
~/prog/tewst) - The previous session is not visible in
/sessions
Root cause:
OpenCode already has an automatic migration mechanism in
project.tsthat reassignsglobalsessions to the correct project at startup. However, it relies on an exact match betweensession.directoryandproject.worktree:db.update(SessionTable) .set({ project_id: data.id }) .where(and( eq(SessionTable.project_id, ProjectID.global), eq(SessionTable.directory, data.worktree) )) .run()
In this scenario,
session.directoryis/home/simon(the launch directory) whileproject.worktreeis/home/simon/prog/tewst. The strict equality check fails and the session remains orphaned inglobal.Confirmed twice:
- Once with a real project where the agent created a Civ 7 modding plugin
- Once with a deliberate reproduction test (
~/prog/tewst)
In both cases, the session data was intact in the SQLite database under
project_id = 'global'and recoverable via a manualUPDATE.Suggested fix:
The migration condition in
project.tscould be relaxed to also match sessions wheresession.directoryis a parent directory ofproject.worktree, not just an exact match. A variant of this scenario (renaming the project directory) would also benefit from a broader matching strategy.Additionally, a cleanup mechanism for orphaned sessions (where
session.directorypoints to a path that no longer exists) could reassign them to the user's home directory so they remain accessible.Environment: OpenCode v1.3.3 on Linux (TUI)
- Start
I've opened #23248 which documents two specific reproduction cases for orphaned sessions caused by directory renaming. The root cause is related — the
directoryfield on sessions is never updated when the project worktree changes.github-actions commented
on Jun 18, 2026 on Jun 18, 2026 – with GitHub ActionsContributorMore actionsTo stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.
Bug Description
When spawning a PTY session from within OpenCode, and then asking the LLM in that nested PTY to perform operations that require session lookup, a
NotFoundErroris thrown because the session is looked up in the wrong project directory.Error Message
Steps to Reproduce
/Users/davidhelmus/Repos/SomeProject)pty_spawn~), which has no.gitDetailed Replication Guide
Prerequisites
~) should NOT be a git repositoryStep-by-Step Replication
1. Verify your home directory is not a git repo
2. Start OpenCode in a git repository
3. Note your session details
The session will be created with:
ses_4423845abffeKHmns5X1nuyqZ6be64773222be3caddeccc7e18daa90049882de9e)~/.local/share/opencode/storage/session/{projectID}/{sessionID}.json4. Spawn a PTY session
Ask the LLM to spawn a PTY:
The LLM will use
pty_spawntool. The PTY's working directory defaults toInstance.directory(the current project directory).5. In the PTY, change to home directory and trigger session lookup
This is the key step. When the PTY runs commands from a non-git directory, and those commands need to look up the parent session:
6. Trigger the error
Ask the LLM to perform any operation that requires looking up the session, such as:
parentID)Why This Happens
When OpenCode runs from
~/(no.git), theProject.fromDirectory()function returns:But the original session was stored under the git project's ID, not "global".
Verification Commands
Check where your session actually exists:
Check the session's projectID:
Root Cause Analysis
Session Storage Architecture
Sessions are stored in project-scoped directories:
For git repositories,
projectIDis the root commit hash (e.g.,be64773222be3caddeccc7e18daa90049882de9e).For non-git directories,
projectIDis"global".The Bug
When a nested PTY session runs from a directory without a git repo (like home directory),
Project.fromDirectory()returnsid: "global":Then when looking up a session, it uses the current
Instance.project.id:This causes the lookup to search in
session/global/instead of the actual project directory where the session was created.Code Flow That Triggers the Bug
PTY Creation (
src/pty/index.ts):Server Request Handling (
src/server/server.tsline 252):When
process.cwd()is~/, the Instance getsprojectID: "global".Session Lookup (
src/session/index.tsline 231):Example
be64773...session/be64773.../ses_442...json~/)globalsession/global/ses_442...jsonEnvironment
Suggested Fixes
Session-to-project index: Create a global index mapping session IDs to their project IDs, enabling cross-project lookups.
Fallback search: When a session isn't found in the current project, search other project directories.
Preserve directory context: When spawning PTY sessions, pass the original directory context via environment variable or header so nested operations use the correct project.
Include project ID in session references: When session IDs are passed between contexts (e.g.,
parentID), include the project ID.Workaround
Ensure PTY sessions that will run OpenCode commands are spawned from within a git repository directory, not from home or other non-git directories. When using
pty_spawn, explicitly set thecwdparameter to the project directory.Related Code
src/storage/storage.ts-withErrorHandling()throws NotFoundError (line 204)src/project/project.ts-fromDirectory()determines project ID (lines 47-170)src/session/index.ts-get()usesInstance.project.idfor lookup (line 231)src/project/instance.ts-Instancecontext managementsrc/pty/index.ts- PTY creation usesInstance.directoryfor cwd (line 104)src/server/server.ts- Request handling determines directory context (line 252)