Skip to content

fix: resolve symlinks in Instance cache key to prevent duplicate instances #16648

@jmylchreest

Description

@jmylchreest

Description

Instance.provide() uses Filesystem.resolve() (which calls path.resolve()) to normalize the directory path before using it as a cache key. However, path.resolve() does not resolve symlinks — it only normalizes . / .. segments and makes the path absolute.

When opencode is launched from a symlinked directory (e.g., ~/src-office~/dtkr4-cnjjf), the TUI thread and worker can end up with different path representations of the same physical directory. This causes Instance.provide() to create two separate Instance contexts — one for each path string.

Because the Bus pub/sub system is Instance-scoped (via Instance.state()), events published on one Instance (where the LLM session runs) are never received by subscribers on the other Instance (where the SSE endpoint is listening). The result is a completely blank TUI — no messages, no parts, no output at all after sending a prompt.

Root Cause

// Instance.provide() — before fix
const directory = Filesystem.resolve(input.directory)  // path.resolve() — does NOT resolve symlinks
let existing = cache.get(directory)  // Different strings for same physical dir → cache miss → duplicate Instance

Fix

Add fs.realpathSync() before Filesystem.resolve() so symlinks are resolved to canonical paths:

const directory = Filesystem.resolve(fs.realpathSync(input.directory))

This ensures the same physical directory always maps to a single Instance, regardless of how it was reached.

Related

This fix is defense-in-depth: even if callers canonicalize their paths, Instance.provide() should not silently create duplicates for symlinked paths.

OpenCode version

dev (current HEAD)

Operating System

Linux

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions