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
Description
Instance.provide()usesFilesystem.resolve()(which callspath.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 causesInstance.provide()to create two separate Instance contexts — one for each path string.Because the
Buspub/sub system is Instance-scoped (viaInstance.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
Fix
Add
fs.realpathSync()beforeFilesystem.resolve()so symlinks are resolved to canonical paths: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