Skip to content

[BUG]: Project ID collision when repos cloned from same source share sessions #6696

Description

@bcheung

Repos cloned from the same source share the same root commit hash, causing them to share sessions unexpectedly. Opening opencode in either repo shows sessions from both.

Affected workflows

  • Cloned templates (e.g., create-react-app, Next.js starters)
  • Forks
  • Any "clone and change origin" workflow

Reproduction

#!/bin/bash
set -e

WORKDIR=$(mktemp -d)
cd "$WORKDIR"

# Create template repo and clone it twice
mkdir template && cd template
git init -q && echo "template" > README.md && git add . && git commit -qm "init"
cd "$WORKDIR"
git clone -q template clone-a
git clone -q template clone-b

# Run opencode in each
(cd "$WORKDIR/clone-a" && opencode run "respond with only: session from clone-a")
(cd "$WORKDIR/clone-b" && opencode run "respond with only: session from clone-b")

# Verify collision
echo "clone-a project ID: $(cat "$WORKDIR/clone-a/.git/opencode")"
echo "clone-b project ID: $(cat "$WORKDIR/clone-b/.git/opencode")"
# Both are identical - opening opencode in either shows sessions from both

Root cause

Project ID is derived from the first root commit hash:

if (!id) {
const roots = await $`git rev-list --max-parents=0 --all`
.quiet()
.nothrow()
.cwd(worktree)
.text()
.then((x) =>
x
.split("\n")
.filter(Boolean)
.map((x) => x.trim())
.toSorted(),
)
id = roots[0]
if (id) Bun.file(path.join(git, "opencode")).write(id)
}

Related

Notes on solution

The fix probably needs to be conditional:

  • Worktree → Share project ID with main repo (current behavior is correct for this case)
  • Git repo (not worktree) → Need deterministic unique ID that doesn't collide across clones. Root commit alone isn't sufficient. Options: include absolute path in hash, or remote origin URL, or generate UUID on first run.
  • Not a git repo → Could use absolute path

Key insight: PR #5647 correctly handles worktrees. This issue is specifically about the non-worktree clone scenario.

Side note: worktree caching

In git worktrees, .git is a file (not directory) pointing to .git/worktrees/<name>/. The current cache write to .git/opencode fails silently. Depending on the solution chosen here, this silent failure may cause issues if the fix relies on persisting something to that file.

let id = await Bun.file(path.join(git, "opencode"))
.text()
.then((x) => x.trim())
.catch(() => {})

Activity

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions