Skip to content

[STG-2477] test(cli): fix flaky Windows EBUSY temp-dir cleanup in functions dev test#2321

Merged
shrey150 merged 1 commit into
mainfrom
shrey/fix-functions-dev-windows-flake
Jul 7, 2026
Merged

[STG-2477] test(cli): fix flaky Windows EBUSY temp-dir cleanup in functions dev test#2321
shrey150 merged 1 commit into
mainfrom
shrey/fix-functions-dev-windows-flake

Conversation

@shrey150

@shrey150 shrey150 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes an intermittent Windows-only CI failure in packages/cli/tests/cli-functions-contract.test.ts.

Failing test: functions scaffolding and local dev > runs a local dev server and invokes a function

Observed error (Windows CI only):

Error: EBUSY: resource busy or locked, rmdir 'C:\...\Temp\functions-dev-XXXX'

Root cause

The test spawns browse functions dev, which in turn spawns a runtime subprocess (a grandchild of the test). The afterEach cleanup does child.kill("SIGTERM") + waitForExit(child) — but on Windows kill only terminates the direct child, not the grandchild runtime. That grandchild can still hold open file handles inside the per-test temp dir when cleanup runs.

The subsequent rm(path, { recursive: true, force: true }) then hits a directory with live handles, and Windows refuses to remove it → EBUSY. Critically, force: true only ignores missing paths; it does not retry on EBUSY. Node's fs.rm exposes maxRetries/retryDelay precisely to retry transient Windows EBUSY/EPERM/ENOTEMPTY errors during recursive removal.

Fix

Add retry options to the temp-dir cleanup rm(...) call in afterEach:

await rm(path, {
  recursive: true,
  force: true,
  maxRetries: 5,
  retryDelay: 100,
});

This is the only rm/rmdir call in the file that removes temp dirs.

Scope / impact

  • Test-only change. No production/source code touched.
  • No changeset (non-release, no runtime behavior change).

E2E Test Matrix

Command / flow Observed output Confidence / sufficiency
pnpm vitest run tests/cli-functions-contract.test.ts (in <worktree>/packages/cli, after pnpm install --frozen-lockfile + pnpm turbo run build --filter=browse...) Test Files 1 passed (1) / Tests 13 passed (13); verbose shows ✓ ... runs a local dev server and invokes a function 626ms Proves no regression on POSIX (macOS) — all 13 tests including the previously-flaky one still pass with the retry options. The Windows EBUSY path can't be reproduced on macOS (POSIX unlinks directories with open handles), so this run cannot exercise the retry itself; the maxRetries/retryDelay options are the canonical, documented Node remedy for Windows EBUSY/EPERM/ENOTEMPTY on recursive rm.
npx prettier --check tests/cli-functions-contract.test.ts All matched files use Prettier code style! Formatting passes — no CI format failure.
npx eslint tests/cli-functions-contract.test.ts exit 0, no output Lint passes.

Linear

STG-2477

🤖 Generated with Claude Code


Summary by cubic

Fixes a Windows-only flaky test by retrying temp-dir cleanup in packages/cli/tests/cli-functions-contract.test.ts to avoid EBUSY during the functions dev test. Addresses STG-2477 and stabilizes CI without touching production code.

  • Bug Fixes
    • Add maxRetries: 5 and retryDelay: 100 to fs.rm in the test afterEach cleanup.
    • Prevents transient EBUSY/EPERM/ENOTEMPTY errors when a grandchild process holds open handles on Windows.

Written for commit c17987a. Summary will update on new commits.

Review in cubic

…ions dev test

The functions dev test spawns `browse functions dev`, which itself spawns a
runtime subprocess (a grandchild). afterEach kills only the direct child via
SIGTERM, so on Windows the grandchild runtime can still hold open handles inside
the temp dir when `rm(path, { recursive, force })` runs. `force: true` ignores
missing paths but does NOT retry EBUSY, so Windows CI intermittently fails with
`EBUSY: resource busy or locked, rmdir`.

Add fs.rm's maxRetries/retryDelay options, which exist specifically to retry
transient Windows EBUSY/EPERM/ENOTEMPTY errors during recursive removal.

Test-only change; no runtime/source impact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: c17987a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 1 file

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@shrey150
shrey150 requested a review from ajmcquilkin July 7, 2026 00:19
@shrey150
shrey150 merged commit 2b750df into main Jul 7, 2026
37 checks passed
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.

2 participants