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
Web & Desktop home UIs render no projects/sessions against a headless server (v1.18.19) although GET /project returns the registered git project #44216
opencode web v1.18.19 headless on Ubuntu 24.04 (systemd), --hostname 127.0.0.1 --port 4096, WorkingDirectory set to a git repository (/opt/data/aicoding/repos/ai-prentice-4-all).
Clients tested: web UI via HTTPS reverse proxy (Chrome, normal + private windows), Desktop app 1.18.x (macOS arm64) connected via defaultServerUrl (tunnel), TUI via opencode attach.
Expected
Home UI lists the server's project (the git repo) and its sessions; "+"/Add project usable.
Actual
Web home shows Nothing here yet / Create a session to get started; Add project greyed; no project nodes (also with ?directory=<repo> in the URL and in a clean private window).
Desktop shows the server as connected (green dot, Default Server) but lists no sessions/projects; its Add project opens the local OS file picker (useless for a remote server).
TUI (opencode attach) works fine and lists sessions — so the server itself is healthy.
GET /session?directory=<repo> returns sessions with that projectID. GET /global/health = {"healthy":true}.
Tried
POST /session?directory=<repo> (registers project correctly; UI still empty).
POST /experimental/workspace {"type":"worktree"} → WorkspaceCreateError: Timed out waiting for global event (and, before the project existed, Worktrees are only supported for git projects).
Setting server cwd to the git repo (project then auto-registers; UI still empty).
Private/incognito windows; hard reloads.
Impact
Headless deployments (the documented opencode serve/opencode web use-case) have no usable web/desktop home; only the TUI works. Related: #7790, #7371.
Suggestion
Home should render GET /project results regardless of workspace layer; web needs a server-side directory picker instead of the OS picker; workspace creation should not hang (Timed out waiting for global event).
Hit this from a different deployment shape — desktop app on macOS against opencode serve inside a dev container — and found something that might narrow it down. In my case the desktop app listed some sessions rather than none, and which ones it listed turned out to depend entirely on one string.
The asymmetry: the directory is normalised on write but matched exactly on read.
The repo is bind-mounted into the container at /workspaces/<repo>. The desktop app's project picker is the native macOS one, so it can only ever send the host path, /Users/<user>/Projects/<repo>.
I first made that host path resolve inside the container with a symlink to /workspaces/<repo>. Prompts then worked, but the session list was empty. Looking in the database:
sqlite> SELECT directory, COUNT(*) FROM session GROUP BY directory;
/workspaces/<repo> 15
/Users/<user>/Projects/<repo> 3
Querying the server the way each client does:
GET /api/session?directory=/workspaces/<repo> -> 15
GET /api/session?directory=/Users/<user>/Projects/<repo> -> 0
The desktop app asks for the second and gets nothing. The three rows that did carry the host path were all created before the symlink existed — at that point realPath failed outright, so the raw client string got stored. Once the symlink was in place, realPath resolved it to /workspaces/<repo> and every new session was filed under a path the app never asks about — including sessions the app itself had just created.
So: the write path resolves symlinks, the read path compares strings. Any deployment where the client's path and the server's resolved path differ ends up with a list that is empty (or partially populated, if some rows predate the mismatch).
Workaround, for anyone else on dev containers: don't use a symlink — mount the checkout a second time at the exact path the host uses:
A bind mount has nothing to resolve, so realPath returns the same string the client sent and write/read agree. After also rewriting the existing rows (session.directory, session.path, project.worktree, project_directory.directory) to the host path, both the desktop app and the web UI list everything — the web UI follows the project record, and that path is now valid on both sides.
That last part may be the useful bit for a fix: pick one canonical form for the directory, and apply it in both directions. Resolving on write while matching raw on read cannot agree unless the two paths happen to be identical.
Environment: desktop app 1.18.21 (macOS arm64), opencode serve 1.18.21 in a Debian dev container, plain HTTP to 127.0.0.1:4096, no workspaces (session.workspace_id is null throughout).
Still reproduces on v1.18.23 (server opencode web headless + clean private-window browser client). GET /project returns the git project with worktree and vcs: git; home remains empty, Add project greyed. PR #39732 not merged; no changelog mention in 1.18.22/23. Watching releases daily.
Related: #46520 is a 1-file fix for one of the causes — Home/Desktop dropping sessions that belong to the global project (created outside a git repo), because their directory never matches the global worktree /.
Note it won't cover the empty client-side project registry case (that's the separate #45011 thread), so if your install has no projects registered at all this may not be the whole story. But if sessions exist and the API returns them, it's worth a look — and a 👍 on #46520 helps it survive the cleanup bot's age/reaction rule.
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.
Activity
github-actions commentedon Aug 22, 2026
This issue might be a duplicate of existing issues. Please check:
blue126 commentedon Aug 23, 2026
Hit this from a different deployment shape — desktop app on macOS against
opencode serveinside a dev container — and found something that might narrow it down. In my case the desktop app listed some sessions rather than none, and which ones it listed turned out to depend entirely on one string.The asymmetry: the directory is normalised on write but matched exactly on read.
The repo is bind-mounted into the container at
/workspaces/<repo>. The desktop app's project picker is the native macOS one, so it can only ever send the host path,/Users/<user>/Projects/<repo>.I first made that host path resolve inside the container with a symlink to
/workspaces/<repo>. Prompts then worked, but the session list was empty. Looking in the database:Querying the server the way each client does:
The desktop app asks for the second and gets nothing. The three rows that did carry the host path were all created before the symlink existed — at that point
realPathfailed outright, so the raw client string got stored. Once the symlink was in place,realPathresolved it to/workspaces/<repo>and every new session was filed under a path the app never asks about — including sessions the app itself had just created.So: the write path resolves symlinks, the read path compares strings. Any deployment where the client's path and the server's resolved path differ ends up with a list that is empty (or partially populated, if some rows predate the mismatch).
Workaround, for anyone else on dev containers: don't use a symlink — mount the checkout a second time at the exact path the host uses:
A bind mount has nothing to resolve, so
realPathreturns the same string the client sent and write/read agree. After also rewriting the existing rows (session.directory,session.path,project.worktree,project_directory.directory) to the host path, both the desktop app and the web UI list everything — the web UI follows the project record, and that path is now valid on both sides.That last part may be the useful bit for a fix: pick one canonical form for the directory, and apply it in both directions. Resolving on write while matching raw on read cannot agree unless the two paths happen to be identical.
Environment: desktop app 1.18.21 (macOS arm64),
opencode serve1.18.21 in a Debian dev container, plain HTTP to127.0.0.1:4096, no workspaces (session.workspace_idis null throughout).leolau commentedon Aug 25, 2026
Still reproduces on v1.18.23 (server
opencode webheadless + clean private-window browser client).GET /projectreturns the git project withworktreeandvcs: git; home remains empty, Add project greyed. PR #39732 not merged; no changelog mention in 1.18.22/23. Watching releases daily.Mattheinrichs commentedon Sep 21, 2026
Related: #46520 is a 1-file fix for one of the causes — Home/Desktop dropping sessions that belong to the
globalproject (created outside a git repo), because their directory never matches the global worktree/.Note it won't cover the empty client-side project registry case (that's the separate #45011 thread), so if your install has no projects registered at all this may not be the whole story. But if sessions exist and the API returns them, it's worth a look — and a 👍 on #46520 helps it survive the cleanup bot's age/reaction rule.
thdxr commentedon Oct 11, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊