Skip to content

Project rename affects all sub-folder workspaces of the same git repo (should be per-workspace) #18276

@Skeptomenos

Description

@Skeptomenos

Bug Description

When working with multiple sub-folders of the same git repository as separate sidebar entries, renaming one project renames all of them. Conversely, if you rename one back, the other gets renamed to the previous name.

Reproduction Steps

  1. Open a project at its git root, e.g. ~/repos/my-project — name it "My Project"
  2. Open a sub-folder of the same repo, e.g. ~/repos/my-project/apps/service-a — it inherits "My Project"
  3. Rename the sub-folder entry to "Service A"
  4. Observe: "My Project" (root) is now also named "Service A"
  5. Rename it back to "My Project"
  6. Observe: "Service A" (sub-folder) is now also named "My Project"

Root Cause

OpenCode identifies projects by their git root commit hash (not by the working directory path). All worktrees within the same git repository share a single project.name row in the SQLite DB.

The enrich() function in packages/app/src/context/layout.tsx has a two-tier name resolution system, but the per-workspace tier is only applied to non-git projects (projectID === "global"):

const isGlobal = projectID === "global" || (metadata?.id === undefined && localOverride)

if (!isGlobal) return base  // ← git projects exit here
                             //   local?.name from workspace .dat is IGNORED

return {                     // ← only non-git projects reach this
  ...base,
  name: local?.name,         // per-workspace name from workspace:project .dat key
}

The infrastructure for per-workspace names already exists — workspace:project in per-workspace .dat files stores ProjectMeta including a name field. This is used correctly for non-git projects (added in bcf7a65e). The fix is to apply the same logic to git projects when a local workspace name is set.

Proposed Fix

packages/app/src/context/layout.tsx — extend enrich() to check local name for git projects:

// Check workspace-level name override even for git projects
if (!isGlobal) {
  if (local?.name !== undefined) {
    return { ...base, name: local.name }
  }
  return base
}

packages/app/src/components/dialog-edit-project.tsx — route rename to workspace storage when in a sub-folder:

const isSubfolder = props.project.directory !== props.project.worktree

if (isSubfolder) {
  // Sub-folder: write to per-workspace .dat only (does not affect root or other sub-folders)
  globalSync.project.meta(props.project.directory, { name, icon, commands })
} else {
  // Git root: update server DB (global rename — existing behavior)
  await globalSDK.client.project.update({ projectID: props.project.id, ... })
}

Expected Behavior

  • Renaming a project at the git root directory → renames globally across all worktrees (existing behavior)
  • Renaming a project while working in a sub-folder → renames that sidebar entry only (per-workspace)

Additional Context

  • Version: 1.2.27
  • The workspace:project per-workspace storage already exists and is used correctly for non-git projects since bcf7a65e (Jan 23, 2026)
  • The issue only manifests once a custom name is set — before that, displayName() falls back to getFilename(worktree) which is per-path and works correctly
  • Sub-folder sessions already correctly use their specific directory as CWD — only the display name is broken

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