Skip to content

fix(isolation): raise worktree git-operation timeout to 5m (supersedes #1029, closes #1119)#1306

Merged
Wirasm merged 1 commit intodevfrom
fix/worktree-git-timeout-default
Apr 20, 2026
Merged

fix(isolation): raise worktree git-operation timeout to 5m (supersedes #1029, closes #1119)#1306
Wirasm merged 1 commit intodevfrom
fix/worktree-git-timeout-default

Conversation

@Wirasm
Copy link
Copy Markdown
Collaborator

@Wirasm Wirasm commented Apr 20, 2026

Summary

  • Problem: All 15 git-subprocess call sites in WorktreeProvider hardcoded timeout: 30000. Repos with heavy post-checkout hooks (lint, dependency install, submodule init) exceed that budget and fail worktree creation.
  • Why it matters: Worktree isolation is unusable for such repos — an agent run dies at setup with no path forward.
  • What changed: Consolidated all 15 timeouts onto a single GIT_OPERATION_TIMEOUT_MS = 5 * 60 * 1000 constant at the top of worktree.ts. 5 min is generous enough to cover realistic hook workloads while still catching genuine hangs (credential prompts in non-TTY, stalled fetches).
  • What did not change (scope boundary): No new config key, no new env var, no changes to @archon/git, MergedConfig, or GlobalConfig. Other timeout: usages outside WorktreeProvider are untouched.

Why this instead of a config key (supersedes #1029)

#1029 proposed a .archon/config.yaml worktree.timeout option. That approach:

  • Adds permanent config surface (doc + maintenance cost) for a problem reported by a single user
  • Half-measures the fix: 11 of 15 hardcoded sites become configurable, 4 stay hardcoded
  • Introduces user-facing choice where a sensible default removes the need

Raising the default covers the reported case with zero API surface. If 5 min later turns out to also be too tight in real-world use, the config key stays an option on the table.

UX Journey

Before

  User                 WorktreeProvider              git subprocess
  ────                 ────────────────              ──────────────
  runs workflow ─────▶ worktree.add ────────────────▶ runs post-checkout hook
                       (30s timeout)                  (lint/install: 45s)
                                                      ↳ TIMEOUT ❌
                       surfaces error ◀──────────────
  sees failure ◀──────

After

  User                 WorktreeProvider              git subprocess
  ────                 ────────────────              ──────────────
  runs workflow ─────▶ worktree.add ────────────────▶ runs post-checkout hook
                       *(5m timeout)*                 (lint/install: 45s)
                                                      ↳ completes ✅
                       returns env ◀──────────────────
  workflow runs ◀─────

Architecture Diagram

Before

WorktreeProvider
├─ 15× execFileAsync('git', ..., { timeout: 30000 })
└─ no shared constant

After

WorktreeProvider
├─ [+] const GIT_OPERATION_TIMEOUT_MS = 5 * 60 * 1000
└─ 15× execFileAsync('git', ..., { timeout: GIT_OPERATION_TIMEOUT_MS })

Connection inventory:

From To Status Notes
GIT_OPERATION_TIMEOUT_MS (new local const) 15× execFileAsync call sites in worktree.ts new Single source of truth

No inter-module connections changed.

Label Snapshot

  • Risk: risk: low
  • Size: size: XS
  • Scope: isolation
  • Module: isolation:worktree-provider

Change Metadata

  • Change type: fix
  • Primary scope: isolation

Linked Issue

Validation Evidence (required)

bun run type-check   # ✅ all 10 packages
bun run lint         # ✅ 0 errors, 0 warnings
bun --filter @archon/isolation test  # ✅ 244 tests pass
  • Evidence: type-check/lint/test runs locally, green.
  • Nothing intentionally skipped.

Security Impact (required)

  • New permissions/capabilities? No
  • New external network calls? No
  • Secrets/tokens handling changed? No
  • File system access scope changed? No

Compatibility / Migration

  • Backward compatible? Yes — behavior change is strictly "waits longer before timing out"
  • Config/env changes? No
  • Database migration needed? No

Human Verification (required)

  • Verified scenarios: Type-check, lint, isolation test suite all pass locally.
  • Edge cases checked: Constant is applied consistently to all 15 call sites (creation, PR fetch/checkout, branch delete, worktree remove). No stray hardcoded 30000 remains in worktree.ts.
  • What was not verified: Live repro against a repo with a >30s post-checkout hook. The change is mechanical — raising a ceiling — and the runtime behavior is directly implied by the constant value.

Side Effects / Blast Radius (required)

  • Affected subsystems/workflows: Any workflow using worktree isolation (i.e. the default path). All other isolation modes untouched.
  • Potential unintended effects: A truly hung git subprocess (e.g. credential prompt in non-TTY) now takes 5 min instead of 30s to surface. Acceptable tradeoff — still surfaces, just later.
  • Guardrails/monitoring for early detection: Existing 'worktree.*_failed' log events fire on timeout-derived errors. No new monitoring needed.

Rollback Plan (required)

  • Fast rollback command/path: git revert <commit> — single-file, single-constant change.
  • Feature flags or config toggles: N/A.
  • Observable failure symptoms: Worktree operations time out at 5 min instead of 30s (prior behavior). If even 5 min proves too tight, revisit with feat(isolation): add configurable worktree creation timeout #1029's config-key approach.

Risks and Mitigations

  • Risk: A truly stuck git subprocess now takes 5× longer to surface (30s → 5m).
    • Mitigation: The prior 30s ceiling was often too low to be diagnostic (failures masked as "hooks slow" vs. "actually hung"). 5 min is still a bounded ceiling and the user can always abort.

Credit to @norbinsh for raising #1119 and scoping the problem clearly in #1029.

Summary by CodeRabbit

  • Chores
    • Improved code consistency for internal git timeout handling.

All 15 worktree git-subprocess timeouts in WorktreeProvider were hardcoded
at 30000ms. Repos with heavy post-checkout hooks (lint, dependency install,
submodule init) routinely exceed that budget and fail worktree creation.

Consolidate them onto a single GIT_OPERATION_TIMEOUT_MS constant at 5 min.
Generous enough to cover reported cases while still catching genuine hangs
(credential prompts in non-TTY, stalled fetches).

Chosen over the config-key approach in #1029 to avoid adding permanent
.archon/config.yaml surface for a problem a raised default solves cleanly.
If 5 min turns out to also be too tight for real-world use, we'll revisit.

Closes #1119
Supersedes #1029

Co-authored-by: Shay Elmualem <12733941+norbinsh@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 20, 2026

📝 Walkthrough

Walkthrough

A new shared constant GIT_OPERATION_TIMEOUT_MS (5 minutes) is introduced to unify timeout values across worktree-related git subprocess calls, replacing multiple hard-coded 30000 millisecond values while preserving different timeouts for other operations.

Changes

Cohort / File(s) Summary
Worktree Timeout Centralization
packages/isolation/src/providers/worktree.ts
Introduced shared constant GIT_OPERATION_TIMEOUT_MS = 5 * 60 * 1000 and replaced hard-coded timeout: 30000 values across worktree removal, branch deletion, remote branch deletion, PR fetch/worktree add/checkout, stale-branch retry deletion, and new worktree branch creation operations. Other unrelated timeouts (prune, submodule init) remain unchanged.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

Poem

🐰 A constant born of patience true,
Five minutes long for tasks to brew,
No magic numbers left behind,
Just unified timeouts, clearly defined! ⏱️✨

🚥 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
Title check ✅ Passed Title clearly summarizes the main change: raising worktree git-operation timeout from 30s to 5m and indicates it supersedes/closes related issues.
Description check ✅ Passed Description follows the template with all major sections completed: Summary with problem/why-it-matters/what-changed/scope, UX Journey, Architecture Diagram, Labels, Change Metadata, Linked Issues, Validation Evidence, Security Impact, Compatibility, Human Verification, Side Effects, Rollback Plan, and Risks/Mitigations.
Linked Issues check ✅ Passed The PR successfully addresses the objective of #1119 by eliminating the 30s timeout failure mode. It raises the timeout to 5m instead of adding config (the alternative proposed in #1029), directly solving the reported issue of repos with slow post-checkout hooks timing out.
Out of Scope Changes check ✅ Passed All changes are scoped to worktree.ts within WorktreeProvider. The PR consolidates 15 hardcoded timeout values into a single constant—no new config keys, env vars, or changes to @archon/git or global config, all within the stated scope boundary.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/worktree-git-timeout-default

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.

Copy link
Copy Markdown

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

🧹 Nitpick comments (1)
packages/isolation/src/providers/worktree.ts (1)

1024-1029: Minor inconsistency: adjacent branch -f still uses 10000.

In the same fallback path, branch -f at line 1025 retains a 10s timeout while the surrounding worktree add now uses GIT_OPERATION_TIMEOUT_MS. branch -f is normally instantaneous, so this is not a correctness issue, but it's the one remaining hardcoded branch-op timeout inside WorktreeProvider and could confuse future readers about which operations are covered by the new ceiling. Consider either switching it to GIT_OPERATION_TIMEOUT_MS for uniformity or adding a brief comment noting why it deliberately stays short. Non-blocking.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/isolation/src/providers/worktree.ts` around lines 1024 - 1029,
Replace the hardcoded 10000 timeout in the execFileAsync call that runs "git ...
branch -f" with the GIT_OPERATION_TIMEOUT_MS constant for consistency with the
adjacent "git worktree add" call; locate the execFileAsync invocation that uses
repoPath, branchName, and startPoint (in WorktreeProvider / worktree.ts) and
swap the numeric timeout to GIT_OPERATION_TIMEOUT_MS (or alternatively add a
one-line comment explaining why this specific branch-op should remain short if
you prefer to keep 10s).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/isolation/src/providers/worktree.ts`:
- Around line 1024-1029: Replace the hardcoded 10000 timeout in the
execFileAsync call that runs "git ... branch -f" with the
GIT_OPERATION_TIMEOUT_MS constant for consistency with the adjacent "git
worktree add" call; locate the execFileAsync invocation that uses repoPath,
branchName, and startPoint (in WorktreeProvider / worktree.ts) and swap the
numeric timeout to GIT_OPERATION_TIMEOUT_MS (or alternatively add a one-line
comment explaining why this specific branch-op should remain short if you prefer
to keep 10s).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 94d42673-c963-4daa-b172-1b0146d37766

📥 Commits

Reviewing files that changed from the base of the PR and between 52eebf9 and e22fcd3.

📒 Files selected for processing (1)
  • packages/isolation/src/providers/worktree.ts

@Wirasm Wirasm merged commit cc78071 into dev Apr 20, 2026
4 checks passed
@Wirasm Wirasm deleted the fix/worktree-git-timeout-default branch April 20, 2026 18:45
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.

feat: configurable worktree creation timeout

1 participant