Skip to content

Project ID changes after git init — sessions disappear from TUI #21230

Closed as not planned

Description

@qwertist

Bug Description

When git init is run in a project directory that already has opencode sessions, the project ID changes and all existing sessions become invisible in the TUI.

Steps to Reproduce

  1. Open opencode in a directory WITHOUT .git (e.g. ~/projects/myapp)
  2. Create a session, do some work
  3. In the session (or externally), run git init && git add . && git commit -m "init"
  4. Restart opencode in the same directory
  5. Expected: Previous sessions are visible
  6. Actual: Previous sessions are gone from TUI

Root Cause

opencode generates project.id differently depending on whether .git exists:

  • No .git: project_id = SHA1(worktree_path) (e.g. 8d7ed93b...)
  • With .git: project_id = git root commit hash (git rev-list --max-parents=0 HEAD) (e.g. 95a72b34...)

When git init happens, opencode creates a NEW project entry with the root commit hash. Sessions linked to the old SHA1-based project ID become orphaned — they exist in the DB but the TUI filters by the new project ID and finds none.

Verified On

  • opencode version: latest (April 2026)
  • Database: ~/.local/share/opencode/opencode.db (SQLite)
  • Affected tables: project, session

Suggested Fix

When resolving a project for a directory, check if another project entry exists for the same worktree path. If found, migrate sessions from the old project to the new one and delete the stale project entry.

Alternatively, use a stable project ID that doesn't change when VCS status changes (e.g. always use the path hash, or always use the path as the key).

Workaround

Manual SQL fix:

UPDATE session SET project_id = '<new_id>' WHERE project_id = '<old_id>';
DELETE FROM project WHERE id = '<old_id>';

We built an automated workaround in our opencode plugin that runs on startup:

  • Computes the correct project ID for each worktree
  • Migrates sessions from stale project entries
  • Deletes duplicate project rows

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Apr 6, 2026
  2. github-actions commented on Apr 6, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  3. added a commit that references this issue on Apr 6, 2026
    01b9f18
  4. rekram1-node commented on Apr 6, 2026

    @rekram1-node
    Contributor
    Image

    Cannot replicate

  5. qwertist commented on Apr 8, 2026

    @qwertist
    Author

    @rekram1-node Thanks for trying. The key is the sequence: the session must exist BEFORE git init.

    Exact reproduction steps

    # 1. Create a directory WITHOUT git
    mkdir /tmp/test-project && cd /tmp/test-project
    echo 'console.log("hi")' > index.js
    
    # 2. Open opencode in it, create a session
    opencode
    # Send any message (e.g. "what files are here?"), then quit (Ctrl+C)
    
    # 3. Verify session exists
    sqlite3 ~/.local/share/opencode/opencode.db \
      "SELECT id, project_id FROM session WHERE directory = '/tmp/test-project' AND parent_id IS NULL"
    # Note the project_id — it will be a SHA1 hash of the path or 'global'
    
    # 4. NOW init git
    cd /tmp/test-project && git init && git add . && git commit -m "init"
    
    # 5. Reopen opencode in the same directory
    opencode
    # The previous session should be GONE from the TUI session list

    Why it happens

    In packages/opencode/src/project/project.ts, fromDirectory():

    • Without .git (step 2): returns id: ProjectID.global (line 177)
    • With .git (step 5): computes id = git rev-list --max-parents=0 HEAD (line 216)

    These are different IDs. A new project row is inserted (line 282-310). Line 313-320 migrates sessions from ProjectID.global to the new ID, BUT only where session.directory = project.worktree. If the directory doesn't exactly match (e.g. the session was created in a subdirectory, or the worktree is /), the migration misses it.

    Also: if the project was created with a non-global ID (e.g. SHA1 of path in older opencode versions), the migration on line 313-320 won't catch it because it only checks ProjectID.global.

    Related

    This is the same root cause as #16995 (worktrees resolve to different project IDs). The fix in our PR #21232 was correct (migrate sessions from stale project entries with same worktree), but the PR was auto-closed for formatting.

    Our workaround

    We run this on every startup in our plugin:

    // For each worktree with multiple project entries:
    // 1. Compute correct project ID (git root commit or SHA1 of path)
    // 2. Migrate sessions from stale project to correct one
    // 3. Delete stale project entry

    Full code: opencode-hub.js fixSessionProjects()

  6. rekram1-node commented on Apr 14, 2026

    @rekram1-node
    Contributor

    @qwertist in my screenshot I demonstrate exactly this:

    The key is the sequence: the session must exist BEFORE git init.

    The session exists prior to the init lol thats exactly ehat i showed u

  7. rekram1-node commented on Apr 14, 2026

    @rekram1-node
    Contributor

    Cannot replicate:

    Image
  8. rekram1-node commented on Apr 14, 2026

    @rekram1-node
    Contributor

    If u continue having issues join our discord and @ me, it will be easier to go back and forth.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions