You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
tui: project configuration errors are not surfaced when opening a directory #55670
A missing file referenced by a project's agent configuration causes a server-side configuration error, but no error is shown in the TUI. The user instead appears to land in another location and cannot access the expected sessions.
Environment
OpenCode: 2.0.29, latest channel
OS: Darwin 27.0.0, arm64
Terminal: Ghostty per runtime diagnostics
Shell: zsh
Server: shared background service
Local plugins: clockwork_cal_refresh.ts, elm_costs.ts, word_count.ts
Not tested without plugins or in standalone mode
Reproduction
Observed with an existing project inside an iCloud-synced Obsidian directory:
Project configuration contains an agent prompt reference:
Move the referenced file without updating the configuration.
Open OpenCode in the affected project.
Observe that the expected sessions are inaccessible, without a visible configuration error.
These are inferred reproduction steps from the observed failure; a minimal isolated reproduction has not been tested.
Expected Behavior
Display an actionable configuration error identifying the configuration file and missing referenced file. Do not silently change location if project initialization fails.
Actual Behavior
No error was shown to the user. OpenCode appeared to open at "root" instead of the intended location; the exact fallback destination was not confirmed.
The server logged:
ConfigInvalidError
PlatformError: NotFound: FileSystem.readFile (<project>/AI Orchestration/Agents/Work.md)
ENOENT: no such file or directory
http.method=GET http.url=/api/fs/list http.status=500
Additional Context
The shared service remained healthy.
Existing project sessions were still retrievable through the API.
Opening a separate test directory worked.
After the user moved the referenced file, the affected project successfully resolved through /api/location. TUI recovery has not yet been confirmed.
The relationship between the configuration failure and apparent location fallback needs investigation.
Thanks for the detailed report. I reproduced this on 2.0.29.
Steps (2.0.29):
Create a project whose opencode.json has an agent with "prompt": "{file:../AI Orchestration/Agents/Work.md}", pointing at a file that doesn't exist.
Run opencode in that project.
Result: the TUI opens with the location shown as ~ instead of the project, and no configuration error is displayed. The same project with a valid reference opens normally. The recording and screenshots below show this.
On the latest dev (4397ee4):
A missing referenced file no longer breaks the project's config. fix(core): substitute empty for missing config file references #55388, merged after 2.0.29, replaces it with an empty string and logs a warning. Your exact case should therefore behave better in the next release.
The TUI still falls back to ~ silently, without showing an error, when the project config fails for another reason. I tested a {file:} reference that points at a directory, and it still lands at ~ (last screenshot). So the main point of this issue, that config errors aren't shown and the location changes silently, still happens on dev.
The script below reproduces both cases (REF=dir for the directory case).
Related: #54786 and its open PR #54804, which cover broken config files being ignored without any message.
recording.mp4
Reproduction script (drive.ts)
// Repro for anomalyco/opencode#55670: a project config whose agent prompt references a// missing file makes the project's Location fail, and the TUI silently falls back to// another location instead of showing the configuration error.//// REF selects the reference: "missing" (default, the reported case) or "dir"// (a {file:} reference pointing at a directory, which still fails on latest dev), or "ok" (control).import{Effect}from"effect"import{OpenCodeDriver}from"opencode-drive"constref=process.env.REF==="dir" ? "{file:./prompts}" : process.env.REF==="ok" ? "{file:./notes.md}" : "{file:../AI Orchestration/Agents/Work.md}"exportdefaultOpenCodeDriver.use({
...(process.env.OC_DEV ? {opencode: {dev: process.env.OC_DEV}} : {}),tui: {recording: true},project: {git: true,files: {"opencode.json": JSON.stringify({$schema: "https://opencode.ai/config.json",agent: {work: {prompt: ref}}},null,2,),"prompts/README.md": "placeholder\n","notes.md": "project file\n",},},},({ ui, opencode })=>Effect.gen(function*(){yield*Effect.sleep(4000)yield*ui.screenshot("tui-after-open")constframe=yield*ui.capture()yield*Effect.log("FRAME:\n"+JSON.stringify(frame).slice(0,4000))}),)
Run it with opencode-drive: opencode-drive run ./drive.ts. It drives opencode from your PATH; set OC_DEV to the path of an OpenCode checkout to run that from source instead.
The TUI resolves its starting location by listing files in process.cwd(). When that request fails for any reason — including the ConfigInvalidError that becomes the GET /api/fs/list 500 in the report above — the cause is discarded and the call silently falls back to api.location.get(), the server's default location. On a shared background service that default is the root, which is the "appeared to open at root" / location shown as ~ symptom, with no error shown.
That also explains why #55388 (merged) improved the missing-file case without closing this issue: it removed one cause of the config failure, not the silent fallback. The directory-reference case reproduced above still fails and still lands at ~.
Intended scope (small, and no behaviour change when the probe succeeds):
stop swallowing the cause in that probe, and surface an actionable error naming the configuration failure instead of quietly swapping the location.
Related but distinct work already in flight: #54804 (broken config files ignored without a message) and #55940 (gating the recovery dialog in LocationProvider.sync on LocationNotFoundError). Neither covers this line — #55940 gates a different signal in the same file, so I will rebase on whichever lands first.
Activity
opencode-agent commentedon Oct 15, 2026
Thanks for the detailed report. I reproduced this on 2.0.29.
Steps (2.0.29):
opencode.jsonhas an agent with"prompt": "{file:../AI Orchestration/Agents/Work.md}", pointing at a file that doesn't exist.opencodein that project.Result: the TUI opens with the location shown as
~instead of the project, and no configuration error is displayed. The same project with a valid reference opens normally. The recording and screenshots below show this.On the latest
dev(4397ee4):~silently, without showing an error, when the project config fails for another reason. I tested a{file:}reference that points at a directory, and it still lands at~(last screenshot). So the main point of this issue, that config errors aren't shown and the location changes silently, still happens ondev.The script below reproduces both cases (
REF=dirfor the directory case).Related: #54786 and its open PR #54804, which cover broken config files being ignored without any message.
recording.mp4
Reproduction script (drive.ts)
Run it with opencode-drive:
opencode-drive run ./drive.ts. It drivesopencodefrom yourPATH; setOC_DEVto the path of an OpenCode checkout to run that from source instead.argszero commentedon Oct 16, 2026
I'd like to work on this.
I traced the silent fallback to the TUI's startup location probe in
packages/tui/src/app.tsx(~L218):The TUI resolves its starting location by listing files in
process.cwd(). When that request fails for any reason — including theConfigInvalidErrorthat becomes theGET /api/fs/list500 in the report above — the cause is discarded and the call silently falls back toapi.location.get(), the server's default location. On a shared background service that default is the root, which is the "appeared to open at root" / location shown as~symptom, with no error shown.That also explains why #55388 (merged) improved the missing-file case without closing this issue: it removed one cause of the config failure, not the silent fallback. The directory-reference case reproduced above still fails and still lands at
~.Intended scope (small, and no behaviour change when the probe succeeds):
Related but distinct work already in flight: #54804 (broken config files ignored without a message) and #55940 (gating the recovery dialog in
LocationProvider.synconLocationNotFoundError). Neither covers this line — #55940 gates a different signal in the same file, so I will rebase on whichever lands first.