Skip to content

Conversation

@ammar-agent
Copy link
Collaborator

@ammar-agent ammar-agent commented Jan 23, 2026

Summary

Fix local workspace fork creating corrupt worktree workspaces by persisting runtimeConfig in config.addWorkspace(), then simplify the codebase by removing redundant inline fallbacks.

Background

PR #1721 (commit 4238ff4) added fork support for local (project-dir) workspaces. The LocalRuntime.forkWorkspace() was correctly implemented to return the project path, and workspaceService.fork() correctly assembled the FrontendWorkspaceMetadata with runtimeConfig: forkedRuntimeConfig.

However, when config.addWorkspace() stored the forked workspace entry, it discarded the runtimeConfig field:

const workspaceEntry: Workspace = {
  path: workspacePath,
  id: metadata.id,
  name: metadata.name,
  createdAt: metadata.createdAt,
  // runtimeConfig was missing!
};

On subsequent config loads, getAllWorkspaceMetadata() would see no runtimeConfig and apply DEFAULT_RUNTIME_CONFIG (type: "worktree" with srcBaseDir), causing the forked workspace to be treated as a worktree runtime. This created "corrupt worktree" errors because WorktreeRuntime operations would fail on directories that were never set up as git worktrees.

Implementation

Commit 1: Fix runtimeConfig persistence

One-line fix: include runtimeConfig: metadata.runtimeConfig in the workspace entry when calling addWorkspace().

Commit 2: Remove redundant fallbacks

The config layer already guarantees every WorkspaceMetadata has a runtimeConfig (via DEFAULT_RUNTIME_CONFIG applied in getAllWorkspaceMetadata()). This commit removes 13 inline ?? { type: "local", srcBaseDir } fallbacks across 5 service files that were:

  • Redundant: The metadata type already includes runtimeConfig
  • Inconsistent: Inline fallbacks used type: "local" while the canonical default is type: "worktree"
  • Bug-masking: Silently substituting values instead of surfacing issues

Files cleaned up:

  • workspaceService.ts (5 locations)
  • agentSession.ts (5 locations)
  • aiService.ts, terminalService.ts, workspaceMcpOverridesService.ts (1 each)

Commit 3: Fix namedWorkspacePath persistence (Codex review feedback)

config.addWorkspace() was hardcoding worktree-style paths (~/.mux/src/...) even for local workspaces. After app restart, this caused Open-in-Editor and path display to use the wrong directory.

Fix: use namedWorkspacePath from the metadata if provided (which is computed runtime-aware by Runtime.getWorkspacePath()), falling back to worktree-style path only for legacy callers.

Validation

  • Integration tests for fork persistence:
    • Creates local workspace → forks → verifies runtimeConfig survives reload
    • Verifies namedWorkspacePath is the project path (not ~/.mux/src/...) after reload
  • make typecheck passes
  • make static-check passes
  • TEST_INTEGRATION=1 bun x jest tests/ipc/forkWorkspace.test.ts - all 9 tests pass

Generated with mux · Model: anthropic:claude-sonnet-4-20250514

@github-actions github-actions bot added the bug label Jan 23, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4f57c255c7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

config.addWorkspace() was not storing the runtimeConfig field from the
metadata, causing forked local workspaces to lose their runtime type.
On reload, getAllWorkspaceMetadata() would apply DEFAULT_RUNTIME_CONFIG
(worktree) instead of preserving the original local config.

This caused forked local workspaces to appear as corrupt worktrees
because WorktreeRuntime operations would fail on directories that
were never set up as git worktrees.

The fix is a one-line change to include runtimeConfig in the
workspace entry when calling addWorkspace().
The WorkspaceMetadataSchema already marks runtimeConfig as required,
and the config layer guarantees it's always set via DEFAULT_RUNTIME_CONFIG.
These inline fallbacks were masking potential bugs instead of surfacing them.

Removed 13 fallbacks from:
- workspaceService.ts (5 locations)
- agentSession.ts (5 locations)
- aiService.ts (1 location)
- terminalService.ts (1 location)
- workspaceMcpOverridesService.ts (1 location)

Net change: -16 lines
Address Codex review feedback: config.addWorkspace() was storing
worktree-style paths (~/.mux/src/...) even for local workspaces.
After reload, this caused Open-in-Editor and path display to use
the wrong directory.

Fix: use namedWorkspacePath if provided (which is computed by the
runtime), falling back to worktree-style path for legacy callers.

Added test assertion to verify namedWorkspacePath persists correctly
through config reload for local workspaces.
@ammar-agent ammar-agent force-pushed the fix-local-fork-runtimeconfig branch from 6a8ab65 to 9129403 Compare January 23, 2026 16:19
@ammario ammario merged commit cf18466 into main Jan 23, 2026
21 of 22 checks passed
@ammario ammario deleted the fix-local-fork-runtimeconfig branch January 23, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants