Skip to content

[BUG]: Session switching doesn't change working directory context #6697

@bcheung

Description

@bcheung

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:

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

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions