docs: add uv cache lock contention handling to worktree skill#500
docs: add uv cache lock contention handling to worktree skill#500
Conversation
Pre-sync venvs sequentially during worktree setup to prevent concurrent uv instances from serializing on the global cache lock. Adds troubleshooting guidance for the lock file location.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a concurrency issue where multiple uv instances, when run simultaneously across different worktrees, can deadlock due to contention for uv's global cache lock. The solution involves introducing a sequential pre-synchronization step for virtual environments during worktree setup, ensuring that uv operations are serialized initially. Additionally, it provides clear instructions for users to manually resolve cache lock issues if they encounter them. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds documentation to the Claude Code worktree skill describing a pre-sync step that runs a sequential per-worktree Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
📝 Coding Plan
Comment |
There was a problem hiding this comment.
Code Review
This pull request adds documentation for handling uv cache lock contention when using worktrees. The changes are helpful, but there are a few areas for improvement. I've suggested a more robust shell command for pre-syncing the venv to avoid silent failures. I've also pointed out and corrected some inaccuracies in the documented cache lock paths for Linux and macOS to ensure the troubleshooting guidance is accurate.
.claude/skills/worktree/SKILL.md
Outdated
| for f in .claude/*.local.*; do test -f "$f" && cp "$f" "<dir-path>/.claude/$(basename "$f")"; done | ||
| ``` | ||
|
|
||
| d. **Pre-sync the venv** to prevent uv cache lock contention when multiple Claude Code instances run concurrently. `uv` uses a global cache lock (`~/.local/uv/cache/.lock` or `$LOCALAPPDATA/uv/cache/.lock`) — if multiple worktrees run `uv run`/`uv sync` simultaneously, they serialize on this lock and all appear to hang. Pre-syncing sequentially here avoids this: |
There was a problem hiding this comment.
The documented path for the uv cache lock on Linux appears incorrect, and the path for macOS is missing. According to uv's documentation, the cache directory is ~/.cache/uv on Linux and ~/Library/Caches/uv on macOS. This line should be updated for accuracy and completeness.
| d. **Pre-sync the venv** to prevent uv cache lock contention when multiple Claude Code instances run concurrently. `uv` uses a global cache lock (`~/.local/uv/cache/.lock` or `$LOCALAPPDATA/uv/cache/.lock`) — if multiple worktrees run `uv run`/`uv sync` simultaneously, they serialize on this lock and all appear to hang. Pre-syncing sequentially here avoids this: | |
| d. **Pre-sync the venv** to prevent uv cache lock contention when multiple Claude Code instances run concurrently. `uv` uses a global cache lock (e.g., `$LOCALAPPDATA/uv/cache/.lock` on Windows, `~/.cache/uv/.lock` on Linux, `~/Library/Caches/uv/.lock` on macOS) — if multiple worktrees run `uv run`/`uv sync` simultaneously, they serialize on this lock and all appear to hang. Pre-syncing sequentially here avoids this: |
.claude/skills/worktree/SKILL.md
Outdated
| d. **Pre-sync the venv** to prevent uv cache lock contention when multiple Claude Code instances run concurrently. `uv` uses a global cache lock (`~/.local/uv/cache/.lock` or `$LOCALAPPDATA/uv/cache/.lock`) — if multiple worktrees run `uv run`/`uv sync` simultaneously, they serialize on this lock and all appear to hang. Pre-syncing sequentially here avoids this: | ||
|
|
||
| ```bash | ||
| cd <dir-path> && uv sync 2>&1 | tail -3; cd - |
There was a problem hiding this comment.
The current command uv sync 2>&1 | tail -3 can mask failures. The pipe to tail -3 suppresses the exit code from uv sync, causing the step to appear successful even if it fails. It can also hide important error messages that are not in the last three lines of output. A more robust command would be to remove the pipe, ensuring that failures are visible and properly reported.
| cd <dir-path> && uv sync 2>&1 | tail -3; cd - | |
| cd <dir-path> && uv sync; cd - |
.claude/skills/worktree/SKILL.md
Outdated
| - Owner/repo (from `git remote`): must match `^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$` | ||
| - Directory paths: must not contain shell metacharacters (`;`, `|`, `&`, `$`, `` ` ``, `(`, `)`) | ||
| - Reject and warn if any value fails validation — do not execute the command. | ||
| - **uv cache lock contention:** `uv` uses a global cache lock file (`$LOCALAPPDATA/uv/cache/.lock` on Windows, `~/.cache/uv/.lock` on Linux/macOS). When multiple worktrees run `uv run` or `uv sync` concurrently, they serialize on this lock, causing all instances to appear stuck. The `setup` command pre-syncs each worktree's venv sequentially to avoid this. If users report all instances hanging on python/uv commands, the fix is: `rm -f "$LOCALAPPDATA/uv/cache/.lock"` (Windows) or `rm -f ~/.cache/uv/.lock` (Linux/macOS). |
There was a problem hiding this comment.
The documented path for the uv cache lock on macOS is incorrect. On macOS, uv uses ~/Library/Caches/uv, not ~/.cache/uv. For clarity and correctness, it's best to list the paths and rm commands for Linux and macOS separately.
| - **uv cache lock contention:** `uv` uses a global cache lock file (`$LOCALAPPDATA/uv/cache/.lock` on Windows, `~/.cache/uv/.lock` on Linux/macOS). When multiple worktrees run `uv run` or `uv sync` concurrently, they serialize on this lock, causing all instances to appear stuck. The `setup` command pre-syncs each worktree's venv sequentially to avoid this. If users report all instances hanging on python/uv commands, the fix is: `rm -f "$LOCALAPPDATA/uv/cache/.lock"` (Windows) or `rm -f ~/.cache/uv/.lock` (Linux/macOS). | |
| - **uv cache lock contention:** `uv` uses a global cache lock file (`$LOCALAPPDATA/uv/cache/.lock` on Windows, `~/.cache/uv/.lock` on Linux, and `~/Library/Caches/uv/.lock` on macOS). When multiple worktrees run `uv run` or `uv sync` concurrently, they serialize on this lock, causing all instances to appear stuck. The `setup` command pre-syncs each worktree's venv sequentially to avoid this. If users report all instances hanging on python/uv commands, the fix is: `rm -f "$LOCALAPPDATA/uv/cache/.lock"` (Windows), `rm -f ~/.cache/uv/.lock` (Linux), or `rm -f ~/Library/Caches/uv/.lock` (macOS). |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.claude/skills/worktree/SKILL.md:
- Around line 140-141: Update the pre-sync venv paragraph in SKILL.md to correct
the Linux/macOS uv cache path from "~/.local/uv/cache/.lock" to the documented
"$HOME/.cache/uv/.lock" (keep the Windows path as
"$LOCALAPPDATA/uv/cache/.lock"), and append a short safety note instructing
users to verify there are no active `uv` processes before removing a stale lock
file (e.g., check `ps`/Task Manager or use `uv` process status) to avoid
corrupting concurrent runs.
- Line 143: The pipeline `cd <dir-path> && uv sync 2>&1 | tail -3; cd -` masks
failures because `tail`'s exit code is returned; either enable `set -o pipefail`
at the top of that script block or replace the pipeline with grouping that
checks `uv sync`'s exit status (e.g. capture PIPESTATUS[0] or test the command
status after the pipeline) so a failing `uv sync` aborts setup, and correct the
documented cache lock path from `~/.local/uv/cache/.lock` to `~/.cache/uv/.lock`
(or reference `$XDG_CACHE_HOME/uv/.lock`) so the documentation matches the
actual uv cache location and line 461.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 758b0c49-3419-4118-8467-5f10a8be4fbd
📒 Files selected for processing (1)
.claude/skills/worktree/SKILL.md
- Correct macOS cache lock path to ~/Library/Caches/uv/.lock (was grouped with Linux as ~/.cache/uv/.lock) - Use $HOME/.cache/uv/.lock for Linux (explicit) - Remove uv sync pipe to tail -3 that masked exit codes - Add safety note: verify no active uv processes before removing stale lock file
🤖 I have created a release *beep* *boop* --- ## [0.3.1](v0.3.0...v0.3.1) (2026-03-17) ### Features * **api:** RFC 9457 Phase 2 — ProblemDetail and content negotiation ([#496](#496)) ([30f7c49](30f7c49)) * **cli:** verify container image signatures and SLSA provenance on pull ([#492](#492)) ([bef272d](bef272d)), closes [#491](#491) * **engine:** implement context budget management in execution loops ([#520](#520)) ([181eb8a](181eb8a)), closes [#416](#416) * implement settings persistence layer (DB-backed config) ([#495](#495)) ([4bd99f7](4bd99f7)), closes [#450](#450) * **memory:** implement dual-mode archival in memory consolidation ([#524](#524)) ([4603c9e](4603c9e)), closes [#418](#418) * migrate config consumers to read through SettingsService ([#510](#510)) ([32f553d](32f553d)) * **settings:** implement settings change subscriptions for service hot-reload ([#526](#526)) ([53f908e](53f908e)), closes [#503](#503) * **settings:** register API config in SettingsService with 2-phase init ([#518](#518)) ([29f7481](29f7481)) * **tools:** add SSRF prevention for git clone URLs ([#505](#505)) ([492dd0d](492dd0d)) * **tools:** wire RootConfig.git_clone to GitCloneTool instantiation ([#519](#519)) ([b7d8172](b7d8172)) ### Bug Fixes * **api:** replace JWT query parameter with one-time ticket for WebSocket auth ([#493](#493)) ([22a25f6](22a25f6)), closes [#343](#343) ### Documentation * add uv cache lock contention handling to worktree skill ([#500](#500)) ([bd85a8d](bd85a8d)) * document RFC 9457 dual response formats in OpenAPI schema ([#506](#506)) ([8dd2524](8dd2524)) ### Maintenance * upgrade jsdom from 28 to 29 ([#499](#499)) ([1ea2249](1ea2249)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
uvinstances from deadlocking on the global cache lockContext
When multiple worktrees run
uv run/uv syncconcurrently, they serialize onuv's global cache lock file, causing all instances to appear stuck. The fix is to pre-sync each worktree's venv sequentially during setup before parallel work begins.Test plan