Skip to content

🤖 fix: Docker sub-agent container double-creation and sidebar latency - #1506

Merged
ethanndickson merged 6 commits into
mainfrom
docker-runtime-brtw
Jan 8, 2026
Merged

🤖 fix: Docker sub-agent container double-creation and sidebar latency#1506
ethanndickson merged 6 commits into
mainfrom
docker-runtime-brtw

Conversation

@ethanndickson

@ethanndickson ethanndickson commented Jan 8, 2026

Copy link
Copy Markdown
Member

Summary

Two related fixes for Docker runtime sub-agents, plus refactoring and Codex review fixes.

1. Container double-creation fix

When creating a sub-agent workspace in Docker runtime, both forkWorkspace() and initWorkspace() were trying to create the container, causing "Container already exists and is running" errors.

Root cause: TaskService.create() calls forkWorkspace() (which creates the container), then calls initWorkspace() (which also tried to create a container).

Fix: initWorkspace() now detects when the container is already running (from a successful fork) and skips directly to running the init hook. Added checkExistingContainer() method that validates:

  • Container exists and is running
  • Git repo is initialized (.git directory exists)
  • Correct branch is checked out (prevents wrong-branch edge case)

2. Sidebar latency fix

Sub-agent workspaces weren't appearing in the sidebar until container creation completed (~5-15s delay).

Root cause: buildSortedWorkspacesByProject() had a race condition where metadata events arrived before config refresh completed, and the second pass only caught workspaces with status === "creating" (never set for sub-agents).

Fix: Remove the dead status === "creating" check - include any workspace in metadata not yet in config.

3. Credential setup for forked containers (Codex P2)

When reusing forked containers via the skip path, setupContainerAndSyncProject() was bypassed, which meant ~/.gitconfig and gh auth setup-git were never run.

Fix: Extract setupCredentials() method and call it in the skip path before running the init hook.

4. Non-fatal init hook semantics (Codex P1)

Init hook failures should be logged but not prevent workspace usage per docs/hooks/init.mdx.

Fix: runInitHookOnRuntime() logs the exit code but doesn't throw, so hook failures don't trigger container cleanup.

Changes

File Change
src/node/runtime/DockerRuntime.ts Add checkExistingContainer(), setupCredentials(), setupContainerAndSyncProject() helpers; preserve forked containers on failure
src/node/runtime/initHook.ts Add comment clarifying non-fatal hook semantics
src/browser/utils/ui/workspaceFiltering.ts Include all metadata workspaces not yet in config
tests/runtime/runtime.test.ts Add tests for skip-path and container preservation

Testing

  1. Start dev mode: make dev
  2. Create a sub-agent task from any workspace
  3. Verify:
    • Workspace appears in sidebar immediately (not after container starts)
    • No "Container already exists" errors in logs
    • Container creation succeeds on first attempt
    • Init hook failures don't delete the container

Generated with mux • Model: anthropic:claude-opus-4-5 • Thinking: high

Two related fixes for Docker runtime sub-agents:

1. Container double-creation: When creating a sub-agent workspace in Docker
   runtime, both forkWorkspace() and initWorkspace() were trying to create
   the container, causing 'Container already exists' errors. Now
   initWorkspace() detects when the container is already running (from a
   successful fork) and skips directly to running the init hook.

2. Sidebar latency: Sub-agent workspaces weren't appearing in the sidebar
   until container creation completed, even though metadata was emitted
   earlier. The race condition was in buildSortedWorkspacesByProject() which
   only included workspaces from the (stale) projects config, ignoring
   workspaces in workspaceMetadata that hadn't been picked up by
   refreshProjects() yet.

Changes:
- DockerRuntime.ts: Add skip detection for already-running containers,
  extract setupContainerAndSyncProject() helper, preserve forked containers
  on init hook failure
- workspaceFiltering.ts: Include all metadata workspaces not yet in config
  (not just status='creating' which was never actually set)
- runtime.test.ts: Add tests for skip-path and container preservation

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

Copy link
Copy Markdown

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: 6484debb12

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/runtime/DockerRuntime.ts Outdated
- initHook.ts: Throw error when init hook exits with non-zero code,
  so initWorkspace() properly returns { success: false } instead of
  silently succeeding

- DockerRuntime.ts: Before skipping container setup for a running
  container, validate that it has an initialized git repo. If not
  (e.g., crash after docker run but before sync), remove and recreate
  instead of operating on an uninitialized environment
@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

Addressed the container validation concern: before skipping setup for a running container, we now verify that .git exists inside. If a prior crash left a running-but-uninitialized container, we detect it and recreate from scratch instead of operating on an empty environment.

Also fixed init hook failure propagation—runInitHookOnRuntime() now throws on non-zero exit so initWorkspace() properly returns { success: false }.

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

Copy link
Copy Markdown

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: 13c218a34e

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/runtime/DockerRuntime.ts Outdated
Comment thread src/node/runtime/initHook.ts Outdated
@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

Addressed both review comments:

P2 - Branch validation: Refactored container validation into checkExistingContainer() which returns a discriminated union. The method now validates the current branch matches branchName using git rev-parse --abbrev-ref HEAD before returning { action: "skip" }. Wrong branch or failed git command triggers { action: "cleanup" } to recreate the container.

P3 - Double logComplete: Added InitHookError class in initHook.ts. When the init hook fails, runInitHookOnRuntime() logs the real exit code then throws InitHookError. Both DockerRuntime and SSHRuntime catch blocks now check if (!(error instanceof InitHookError)) before calling logComplete(-1), preserving the real exit code.

- Add ContainerCheckResult discriminated union for validation outcomes
- Extract nested validation logic into flat early-return helper method
- Branch validation (P2): check current branch matches branchName before skipping
- Double logComplete (P3): use InitHookError class with instanceof check

Addresses Codex review comments on branch validation and init hook logging.

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

Copy link
Copy Markdown

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: 4728991c95

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/runtime/runtime.test.ts
Tests now initialize containers with branchName instead of 'main' to
match the branch validation in checkExistingContainer().
@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

Fixed: Both tests now initialize the container git repo on ${workspaceName} instead of main, matching what initWorkspace({ branchName: workspaceName }) expects.

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

Copy link
Copy Markdown

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: efff060e38

ℹ️ 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".

Comment thread src/node/runtime/initHook.ts Outdated
Init hook failures should be logged but not prevent workspace usage,
per docs/hooks/init.mdx. Reverting InitHookError approach - the original
design was correct (log exit code, don't throw).

- Remove InitHookError class from initHook.ts
- Remove instanceof checks from Docker/SSH runtime catch blocks
- Update test to expect success=true when hook fails (non-fatal)
@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

Fixed P1: Restored non-fatal init hook semantics per docs/hooks/init.mdx.

  • Removed InitHookError class - the original design was correct (log exit code and return, don't throw)
  • Hook failures now log their exit code but initWorkspace() returns success: true
  • Container cleanup only happens for actual initialization failures (setup, git sync, etc.), not hook failures

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

Copy link
Copy Markdown

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: c54ad3bad7

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/runtime/DockerRuntime.ts
Extract setupCredentials() to copy gitconfig and run gh auth setup-git.
Called in skip path so forked containers get credentials before init hook.

- Add setupCredentials() method for gitconfig + gh auth
- Call in skip path for reused forked containers
- Refactor setupContainerAndSyncProject to use the new method
@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

Fixed P2: Extracted setupCredentials() method and call it in the skip path for reused forked containers.

  • New setupCredentials(containerName, env) method copies ~/.gitconfig and runs gh auth setup-git
  • Called in skip path before init hook runs, so forked containers get credentials
  • setupContainerAndSyncProject() now calls the shared method instead of inline code

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ethanndickson
ethanndickson added this pull request to the merge queue Jan 8, 2026
Merged via the queue into main with commit 67f4121 Jan 8, 2026
21 checks passed
@ethanndickson
ethanndickson deleted the docker-runtime-brtw branch January 8, 2026 05:53
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.

1 participant