Skip to content

fix: handle parallel disk space fallback and expose startup failures#303

Merged
subsy merged 2 commits intomainfrom
fix/issue-295-parallel-disk-space-visibility-v2
Feb 14, 2026
Merged

fix: handle parallel disk space fallback and expose startup failures#303
subsy merged 2 commits intomainfrom
fix/issue-295-parallel-disk-space-visibility-v2

Conversation

@subsy
Copy link
Copy Markdown
Owner

@subsy subsy commented Feb 14, 2026

Summary

  • Add fallback disk space check in WorktreeManager: prefer fs.statfs and fallback to df for APFS/quirky filesystems.
  • Surface parallel run startup failures in the TUI with an inline error toast and preserve state on failure.
  • Add regression tests for the fallback/insufficient-space behavior.
  • Pass failure message through run wrapper/props and clear on restart/start events.

Validation

  • bun run typecheck
  • bun run build
  • bun test src/parallel/worktree-manager.test.ts

Summary by CodeRabbit

  • New Features

    • Parallel-run failures now surface as a visible error status and banner/toast in the UI, retained when appropriate and cleared on restart.
  • Bug Fixes

    • More robust disk-space detection across filesystems with fallback checks to avoid false insufficient-space errors and improve reliability.

@vercel
Copy link
Copy Markdown

vercel bot commented Feb 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ralph-tui Ignored Ignored Preview Feb 14, 2026 10:54am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 14, 2026

Walkthrough

Adds propagation and persistence of a parallel failure message through the run command and TUI, exposes it as a new parallelFailureMessage prop to RunApp, and implements resilient disk-space checks in worktree-manager with new tests for statfs/df fallback behaviour.

Changes

Cohort / File(s) Summary
Parallel failure plumbing
src/commands/run.tsx
Adds parallelFailureMessage to RunAppWrapperProps, introduces applyParallelFailureState to save failure messages into persisted session state and call a persister; threads the message through RunAppWrapper to RunApp.
Parallel runner / TUI state
src/commands/run.tsx (RunParallelWithTui path), src/tui/components/RunApp.tsx
Introduces `failureMessage: string
Disk-space checks (implementation)
src/parallel/worktree-manager.ts
Reworks disk-space validation: reads available bytes from statfs first, falls back to df -k with parsing (helpers getAvailableDiskSpaceFromStatFs, getAvailableDiskSpaceFromDf, parseDfAvailableBytes); treats null available as non-blocking and produces clearer error messages when insufficient.
Disk-space tests
src/parallel/worktree-manager.test.ts
Adds tests and a DiskCheckAccessor mock to validate statfs→df fallback and insufficient-space rejection paths.
Parallel failure tests
src/commands/run.test.ts
Adds tests for applyParallelFailureState ensuring persisted state is updated and startup fallback message is set or preserved as appropriate.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Executor as ParallelExecutor
participant State as ParallelState (in-memory)
participant Persister as PersistedSessionPersister
participant TUI as RunApp / TUI

Executor->>State: on parallel:started -> reset failureMessage
Executor->>State: on parallel:failed (error) -> set failureMessage
Executor->>Persister: call applyParallelFailureState -> persist updated state
Persister-->>State: persisted confirmation
State->>TUI: expose parallelFailureMessage prop
TUI->>TUI: set status=error and render Toast with message

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 4
✅ 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 summarises the main changes: handling disk space fallbacks in WorktreeManager and exposing parallel startup failures in the UI.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/issue-295-parallel-disk-space-visibility-v2

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
src/commands/run.test.ts (1)

649-709: Parallel failure tests are nested inside the unrelated "conflict resolution helpers" describe block.

The describe('parallel failure handling', ...) block is a child of describe('conflict resolution helpers', ...) (line 361). These are logically distinct concerns. Moving it to be a top-level describe sibling would improve discoverability and make the test structure match the module structure.

♻️ Suggested restructuring
-  describe('parallel failure handling', () => {
+});
+
+describe('parallel failure handling', () => {

i.e. close the conflict resolution helpers block before opening parallel failure handling, and add the corresponding closing }); at the end.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 14, 2026

Codecov Report

❌ Patch coverage is 28.81356% with 84 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.48%. Comparing base (df7bd04) to head (16982f1).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
src/parallel/worktree-manager.ts 27.71% 60 Missing ⚠️
src/commands/run.tsx 31.42% 24 Missing ⚠️

❌ Your patch status has failed because the patch coverage (28.81%) is below the target coverage (50.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #303      +/-   ##
==========================================
- Coverage   44.51%   44.48%   -0.04%     
==========================================
  Files          96       96              
  Lines       30175    30283     +108     
==========================================
+ Hits        13432    13470      +38     
- Misses      16743    16813      +70     
Files with missing lines Coverage Δ
src/commands/run.tsx 11.00% <31.42%> (+0.29%) ⬆️
src/parallel/worktree-manager.ts 54.80% <27.71%> (-6.67%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/parallel/worktree-manager.ts (1)

383-446: ⚠️ Potential issue | 🟠 Major

Disk‑space check should target the worktree volume, not cwd.
When worktreeDir sits on another filesystem, checking cwd can misreport free space and either block valid runs or allow failures. Consider checking the worktree path (or its parent if the directory does not exist yet).

🛠️ Suggested fix
-      let available = await this.getAvailableDiskSpaceFromStatFs();
+      const diskCheckPath = fs.existsSync(this.config.worktreeDir)
+        ? this.config.worktreeDir
+        : path.dirname(this.config.worktreeDir);
+      let available = await this.getAvailableDiskSpaceFromStatFs(diskCheckPath);
       if (available === null || available <= 0) {
-        available = await this.getAvailableDiskSpaceFromDf();
+        available = await this.getAvailableDiskSpaceFromDf(diskCheckPath);
       }

-  private async getAvailableDiskSpaceFromStatFs(): Promise<number | null> {
+  private async getAvailableDiskSpaceFromStatFs(targetPath: string): Promise<number | null> {
     try {
-      const stats = await fs.promises.statfs(this.config.cwd);
+      const stats = await fs.promises.statfs(targetPath);
       const available = Number(stats.bavail) * Number(stats.bsize);

-  private getAvailableDiskSpaceFromDf(): number | null {
+  private getAvailableDiskSpaceFromDf(targetPath: string): number | null {
     try {
-      const output = execFileSync('df', ['-k', this.config.cwd], {
+      const output = execFileSync('df', ['-k', targetPath], {
         encoding: 'utf-8',
       });
🤖 Fix all issues with AI agents
In `@src/commands/run.tsx`:
- Around line 1969-1973: When handling the startup-rejection fallback where
parallelState.failureMessage is set, also mark the session as failed and persist
that state so it cannot be resumed; call the session failure helper on the same
object (e.g., parallelState.markFailed(parallelState.failureMessage) or
parallelState.setFailed = true) and then persist it (e.g., await
parallelState.persist() or call the existing persist/save helper used elsewhere
in this file) after setting the failureMessage, ensuring this mirrors how
failures are recorded when the parallel:failed event is emitted and uses the
same helper functions used elsewhere in this module.

@subsy subsy merged commit 1bf4156 into main Feb 14, 2026
8 of 9 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.

1 participant