Skip to content

Fix checkout workspace opening for Windows drive roots#43

Open
dodjdnh wants to merge 1 commit into
Waishnav:mainfrom
dodjdnh:fix/windows-drive-root-checkout
Open

Fix checkout workspace opening for Windows drive roots#43
dodjdnh wants to merge 1 commit into
Waishnav:mainfrom
dodjdnh:fix/windows-drive-root-checkout

Conversation

@dodjdnh

@dodjdnh dodjdnh commented Jun 27, 2026

Copy link
Copy Markdown

Fixes Windows drive-root checkout workspace initialization.

This fixes a Windows-specific checkout workspace issue where opening an existing drive root such as D:\ or E:\ can fail with:

EPERM: operation not permitted, mkdir 'D:\'

Root cause:

openCheckoutWorkspace() called mkdir(root, { recursive: true }) before checking whether the path already existed. That is unnecessary for existing paths and can fail for Windows drive roots.

What changed:

  • Added ensureCheckoutWorkspaceRoot()
  • stat() is now attempted first
  • mkdir(..., { recursive: true }) is only called when stat() fails with ENOENT
  • Existing behavior is preserved for missing checkout workspace directories
  • Added a regression test to ensure existing directories do not call mkdir()

Validation:

  • npm run test
  • npm run typecheck
  • npm run build

Manual QA:

A short Windows manual QA recording will be attached in the PR discussion.

Summary by CodeRabbit

  • Bug Fixes
    • Improved workspace checkout handling so the root directory is verified consistently before use.
    • Existing workspace roots are now detected without creating unnecessary directories.
    • Added coverage to confirm no filesystem changes occur when the checkout root already exists.

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Checkout workspace root setup now goes through a shared helper that checks the path first, creates it only when missing, and returns the resulting directory stats. The test suite adds coverage for the existing-directory case.

Changes

Checkout workspace root handling

Layer / File(s) Summary
Shared root directory helper
src/workspaces.ts
Adds typed filesystem ops, exports ensureCheckoutWorkspaceRoot, and routes openCheckoutWorkspace through it to stat, optionally mkdir on ENOENT, and stat again.
Existing-root test
src/workspaces.test.ts
Imports the helper and adds a test that verifies a pre-existing root is a directory and that mkdir is skipped.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • Issue 34 — matches the checkout root flow that checks for an existing path before attempting recursive directory creation.

Poem

I twitched my nose and hopped along,
The root was there; the stats were strong.
No mkdir thump, no extra fuss,
Just paths and checks and happy us. 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the Windows drive-root checkout workspace fix introduced by the changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
src/workspaces.test.ts (1)

50-63: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the ENOENT creation branch.

This block verifies the existing-directory path (mkdir not called), but the actual fix logic — stat failing with ENOENT, then mkdir(..., { recursive: true }) being invoked and a re-stat returning the created directory — is untested. Consider a sibling case where the mocked stat first throws an ENOENT-coded error and asserts mkdirCalls === 1, plus one asserting a non-ENOENT error is rethrown without calling mkdir.

🧪 Example additional test case
+  {
+    let mkdirCalls = 0;
+    const missing = join(root, "nested-missing-root");
+    const createdStats = await ensureCheckoutWorkspaceRoot(missing, {
+      stat: (() => {
+        let calls = 0;
+        return async (path: string) => {
+          assert.equal(path, missing);
+          calls += 1;
+          if (calls === 1) {
+            const err = new Error("missing") as NodeJS.ErrnoException;
+            err.code = "ENOENT";
+            throw err;
+          }
+          return await stat(path);
+        };
+      })(),
+      mkdir: async (path) => {
+        assert.equal(path, missing);
+        mkdirCalls += 1;
+        await mkdir(path, { recursive: true });
+      },
+    });
+    assert.equal(createdStats.isDirectory(), true);
+    assert.equal(mkdirCalls, 1);
+  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/workspaces.test.ts` around lines 50 - 63, Add test coverage for the
ENOENT branch in ensureCheckoutWorkspaceRoot: create a sibling case where the
mocked stat first throws an error with code ENOENT, then verify mkdir is called
once with recursive behavior and that the subsequent re-stat returns the created
directory. Also add a negative case in the same test file to confirm a
non-ENOENT stat error is rethrown and mkdir is not called, using the existing
ensureCheckoutWorkspaceRoot helper and its stat/mkdir mocks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/workspaces.test.ts`:
- Around line 50-63: Add test coverage for the ENOENT branch in
ensureCheckoutWorkspaceRoot: create a sibling case where the mocked stat first
throws an error with code ENOENT, then verify mkdir is called once with
recursive behavior and that the subsequent re-stat returns the created
directory. Also add a negative case in the same test file to confirm a
non-ENOENT stat error is rethrown and mkdir is not called, using the existing
ensureCheckoutWorkspaceRoot helper and its stat/mkdir mocks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 788ce9b6-cf06-44b7-ae3a-cb58ede2aad0

📥 Commits

Reviewing files that changed from the base of the PR and between 65be252 and 629318c.

📒 Files selected for processing (2)
  • src/workspaces.test.ts
  • src/workspaces.ts

@dodjdnh

dodjdnh commented Jun 27, 2026

Copy link
Copy Markdown
Author
manual-qa-windows-drive-root-compressed.mp4

@dodjdnh

dodjdnh commented Jun 27, 2026

Copy link
Copy Markdown
Author

Manual QA recording attached. Local Windows testing for the drive-root checkout fix:

  • Branch: fix/windows-drive-root-checkout
  • Original failing operation: mkdir("D:\\", { recursive: true }) fails with EPERM
  • Original failing operation: mkdir("E:\\", { recursive: true }) fails with EPERM
  • Fixed DevSpace code path: ensureCheckoutWorkspaceRoot("D:\\") succeeds and returns isDirectory = true
  • Fixed DevSpace code path: ensureCheckoutWorkspaceRoot("E:\\") succeeds and returns isDirectory = true
  • npm run build passes
  • node dist/cli.js doctor shows the temporary QA allowed roots, including D:\, E:\, and E:\MinerU

I also tried running the full ChatGPT + DevSpace open_workspace flow against D:\ / E:\, but the tool call was blocked by OpenAI's safety check before it reached DevSpace. That is a platform-level restriction, not the DevSpace bug, so I verified the Windows filesystem behavior locally against the fixed DevSpace code path instead.

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