Repository navigation
Description
Environment
- opencode Desktop 1.18.30 (Electron, macOS arm64) — the current stable latest release (
v1.18.30, 2026-09-09) - Bundled server DB:
~/.local/share/opencode/opencode.db - Root cause verified directly in the shipped
app.asar(out/main/chunks/node-*.js) as well as in the live DB.
Summary
Renaming a local git repository folder that is already registered as a project leaves project.worktree pointing at the old, now non-existent path forever.
Project identity is derived from the git remote URL, not the directory path, so re-adding the renamed folder resolves to the same project id. Project.fromDirectory then finds the existing row and preserves the old worktree, demoting the new path to sandboxes. The UI derives the project name/path and session scope from project.worktree, so it keeps showing and opening the dead old folder, and new sessions created against it misbehave.
Removing the project from the sidebar and re-adding it does not help, because "remove project" only closes the UI entry and never deletes the DB row.
Steps to reproduce
- Have a git repo at
/Users/me/Documents/old-dirwith anoriginremote. - Open it as a project in the Desktop app and run a few sessions.
- Quit the app, then rename the folder (git remote unchanged):
old-dir→new-dir. - Reopen the app and add
/Users/me/Documents/new-diras a project. - Observe: the project still shows/opens
old-dir; new sessions under it are created relative to the stale root and behave abnormally. Closing ("removing") the project and re-adding repeats the same result.
Root cause (from the shipped 1.18.30 bundle)
Project.resolve:id = remote ?? <cached id in .git/opencode> ?? firstRootCommit, whereremote = sha1("git-remote:" + normalized origin URL). Identity is path-independent.Project.fromDirectory: after selecting the row by id, for every non-globalproject it doesresult5.worktree = existing.worktree; the just-resolved directory is only appended tosandboxeswhendirectory !== worktree. The following upsert writes the staleworktreeback, so it can never heal on its own.- Renderer: sidebar label =
project.name || getFilename(project.worktree); nav slug =base64(project.worktree); session and workspace stores are keyed byworktree. - Sidebar "remove/close project" calls
projects.close(worktree)— it removes the UI entry only; theprojectrow is never deleted, so re-adding always re-hits the same stale row.
Observed DB state (after reproducing)
project.id = <40-hex git-remote hash; unchanged across the rename>
project.worktree = /Users/me/Documents/old-dir <- stale, does not exist
project.sandboxes = ["/Users/me/Documents/new-dir"]
project_directory = { new-dir, new-dir-issue-14 } <- correct new path
The stale worktree is still used as a working directory by the agent/tooling: state files were written under the re-created (previously renamed-away) old path, i.e. a dead path silently gets recreated.
Relation to prior reports
This is the same defect as #35240 ("Server keeps stale project.worktree after project folder is renamed on disk"), which was closed as COMPLETED for the opencode2 launch via #46713. That PR's base branch is v2, so the fix did not reach the v1 line — and the current stable 1.18.30 still contains the un-fixed logic above. Filing here because the behavior persists on the shipping stable release.
Suggested fix
In Project.fromDirectory, when the just-resolved directory exists but the stored worktree no longer does, repoint worktree to the resolved existing directory instead of blindly preserving existing.worktree (only keep the old path if it still exists). Additionally, on startup, when project.worktree is missing, reconcile against project_directory rows so a dead worktree is never advertised to clients.
Workaround (users, app closed)
With the Desktop app fully quit, repoint the row and checkpoint:
UPDATE project
SET worktree = '/Users/me/Documents/new-dir',
sandboxes = '[]'
WHERE id = '<project id>';
PRAGMA wal_checkpoint(TRUNCATE);Then start the app; the project and its existing sessions reopen against the new path.
Drafted with an AI coding assistant on behalf of the reporter.
Activity
github-actions commentedon Sep 10, 2026
This issue might be a duplicate of existing issues. Please check:
project.worktreeafter project folder is renamed on disk; remote clients keep reopening the dead path #35240: Same root cause (staleproject.worktreeafter rename) — closed as fixed via fix(app): keep new local sessions in the selected directory #46713, but that PR targeted thev2branch and may not have landed in v1worktreepath in project DB, causing persistent 500 errors on relaunch #41420: Renaming a project folder leaves staleworktree, causing 500 errors (closed)worktreeinprojecttable — project shows "no git" and all prompts fail with ENOENT #46330: Moving a project directory leaves staleworktree(closed)If the fix from #46713 genuinely did not reach the v1 (1.18.x) line, this may be a valid regression report rather than a strict duplicate — please clarify in a comment whether v1 backport is expected.
binbuf commentedon Sep 22, 2026
Hello, I saw the 2.0 tag. Are there any plans to fix this in 1.x version of OpenCode? This becomes a problem every time renaming projects. I can take a look and submit a PR if interested. Thanks.
AurorahHarmony commentedon Oct 13, 2026
Just lost a few hours to something very similar to this, and it stalled my app rewrite pretty badly. Here's how I managed to reproduce it:
/Users/me/Documents/projthat has an origin remote (e.g.git@github.com:acme/proj.git).projtoproj-moved(leave the git remote alone). Reopen the app and add/Users/me/Documents/proj-movedas a project./Users/me/Documents/proj, andproj-movedjust gets recorded under sandboxes./Users/me/Documents/proj, with a different origin (e.g.git@github.com:acme/other.git)./Users/me/Documents/projas a project via Home → Add project.projandproj-moved(two "creating instance" log lines in the same millisecond).neriousy commentedon Oct 20, 2026
Thanks for the detailed reproduction of the stale
project.worktreeafter renaming a repository. This is fixed in v2: opening the renamed repository replaces its missing canonical directory instead of permanently retaining the old path. v1 now receives only critical fixes; please update the desktop app, or install the v2 CLI withnpm i -g @opencode/cli@latest. If a renamed repository still opens the old path on v2, please open a new issue with the v2 version and reproduction steps.