-
Notifications
You must be signed in to change notification settings - Fork 4k
Description
When switching/resuming sessions, the entire execution context remains bound to Instance.directory (where opencode was started), not the session's stored directory.
What's affected
- System prompt - LLM is told "Working directory: X" but session was created in Y
- All file tools - read, write, edit, grep, glob, ls, patch, multiedit resolve paths relative to wrong directory
- Bash/shell execution - commands run in wrong cwd
- LSP connections - language server bound to wrong project
- File watchers - watching wrong directory
- Snapshots - git operations in wrong repo
- Config loading - may load wrong project config
Impact
- Global project: Sessions from different directories are visible together (this is fine!), but switching to one operates in the current directory, not the session's original directory (this is the bug)
- Worktrees: Can see session from worktree when in main repo, but continuing that session operates in main repo, not the worktree
- Clone collision: Even when sessions are incorrectly mixed due to project ID collision, proper directory switching would at least operate in the right place
Note: Global project and shared sessions across directories isn't inherently bad - it's useful for seeing all your work. The bug is that switching sessions doesn't restore the correct working directory context.
Root cause
Instance.directory is set once at startup and never updated when switching sessions:
opencode/packages/opencode/src/project/instance.ts
Lines 17 to 41 in 038cff4
| async provide<R>(input: { directory: string; init?: () => Promise<any>; fn: () => R }): Promise<R> { | |
| let existing = cache.get(input.directory) | |
| if (!existing) { | |
| Log.Default.info("creating instance", { directory: input.directory }) | |
| existing = iife(async () => { | |
| const project = await Project.fromDirectory(input.directory) | |
| const ctx = { | |
| directory: input.directory, | |
| worktree: project.worktree, | |
| project, | |
| } | |
| await context.provide(ctx, async () => { | |
| await input.init?.() | |
| }) | |
| return ctx | |
| }) | |
| cache.set(input.directory, existing) | |
| } | |
| const ctx = await existing | |
| return context.provide(ctx, async () => { | |
| return input.fn() | |
| }) | |
| }, | |
| get directory() { | |
| return context.use().directory |
It's used throughout the codebase:
session/system.ts - system prompt, config loading
session/prompt.ts - path resolution, shell cwd
tool/*.ts - all file operations
lsp/*.ts - language server
file/watcher.ts - file watching
snapshot/index.ts - git snapshots
Related
- Sessions are now mixed with home directory session list, disregarding which directory you're in #3551 - "Sessions are now mixed with home directory session list"
Expected behavior
When switching/resuming a session, Instance.directory (and related context) should be updated to match session.directory so the entire execution context is correct.
Otherwise, opencode should not be showing sessions with different directories even if within the same project.