Skip to content

fix(opencode): preserve orphan sessions on project id drift#30682

Open
JochenYang wants to merge 2 commits into
anomalyco:devfrom
JochenYang:fix/session-orphan-from-project-id-drift
Open

fix(opencode): preserve orphan sessions on project id drift#30682
JochenYang wants to merge 2 commits into
anomalyco:devfrom
JochenYang:fix/session-orphan-from-project-id-drift

Conversation

@JochenYang

@JochenYang JochenYang commented Jun 4, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #30683

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

For git projects that have no remote URL, the project id is derived from the root commit SHA1. When users rewrite history (rebase --root, filter-repo, filter-branch) and the <git-common-dir>/opencode cache file is lost at the same time, Project.resolve() returns a new project id on the next startup, while the old project row and its sessions are stranded. Project.migrateProjectId previously early-returned on oldID === undefined, and fromDirectory's global->specific fallback only handled project_id = "global", so non-global orphan projects were unreachable from Session.list after restart.

The fix scans project.worktree to recover orphan projects whose worktree matches the current directory, and migrates session, workspace, permission, and project_directory rows before deleting the old project row. All four tables cascade-delete on project removal, so the FK-owned rows must be re-homed first to avoid silently dropping the user's saved permissions and directory metadata. projectV2.commit failure path now logs a warning instead of being silently swallowed.

The new opts.directory parameter on migrateProjectId is optional, so the explicit-cache-hit path is unchanged. fromDirectory is the only caller and is updated to pass the directory.

How did you verify your code works?

  • Added 7 new tests in packages/opencode/test/project/project.test.ts:
    • migrates orphan projects whose worktree matches the current directory
    • does not migrate anything when no project matches the current directory
    • migrates every orphan project whose worktree matches the current directory
    • candidates with global id are excluded
    • permission and project_directory rows are preserved
    • logs warning and continues when writing the opencode cache fails
    • end-to-end: recaptures orphan sessions when project id drifts after history rewrite
  • The end-to-end test reproduces the full bug pattern in it.live (real git, real DB, real fromDirectory): start a project, simulate a root commit rewrite via git commit --amend, drop the cache, call fromDirectory again, and assert the orphan session is recaptured under the new project id. I ran the same test against the unpatched code first to confirm it fails as expected, then against the patched code to confirm it passes.
  • 43/43 tests in the project suite pass
  • typecheck clean (tsgo --noEmit)
  • 253/253 server tests, 14/14 storage tests, 343/343 session tests unchanged
  • Reproduced the original user bug in production (%LOCALAPPDATA%\opencode\opencode.db on Windows): 186 sessions stranded across 4 project_ids for one project (Maxcode), 13 across 2 project_ids for another (iScrcpy). Wrote a separate one-off SQL repair script to recover them, which is not part of this PR.

Screenshots / recordings

Not applicable (no UI change).

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Out of scope

The investigation also surfaced other "session not visible" causes (path = "" filter edge case in listByProject, 30-day hardcoded TUI window, applyUsage not refreshing time_updated). I am not addressing those here. They are separate bugs that the reporter has not observed and should be tracked as follow-up issues if desired.

@github-actions github-actions Bot added needs:issue needs:compliance This means the issue will auto-close after 2 hours. labels Jun 4, 2026
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Related PRs Found

I found two PRs that are related to your current PR (#30682) on project ID and worktree handling:

  1. fix(core): include git store hash in project ID to distinguish indepe… #29977 - fix(core): include git store hash in project ID to distinguish indepe…

    • Related: Both address project ID identification and distinguish projects
  2. fix(project): repair split project IDs across worktrees #14287 - fix(project): repair split project IDs across worktrees

    • Related: Directly addresses worktree-related project ID issues, similar concern of managing projects across different worktree contexts

These are related to the broader problem space of project ID stability and worktree management, but don't appear to be exact duplicates of the current orphan session recovery PR.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Jun 4, 2026
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@JochenYang JochenYang force-pushed the fix/session-orphan-from-project-id-drift branch from 45c3e4d to 0405723 Compare June 10, 2026 01:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: orphan sessions when project id drifts after git history rewrite

1 participant