ANTIGRAVITY LABJP
Articles/App Development
App Development/2026-06-20Advanced

When Parallel Agents Corrupt Your Lockfile: Serializing Dependency Installs in Antigravity

Antigravity's parallel agents racing on the same pnpm store and lockfile can corrupt both. Here is how I kept code generation parallel while serializing only the installs with a file lock.

Antigravity328pnpm2parallel-agents2lockfilenode_modules

Premium Article

One morning, two of the four tasks I had handed to overnight agents had stalled with a "dependency not found" error. As an indie developer running several apps and the Dolice Labs blogs in parallel, I batch my agents during off-peak hours. That night I had split the work across four agents at once: a React screen, a new API route, a lint cleanup, and some test coverage.

What greeted me was a corrupted pnpm-lock.yaml and a half-extracted node_modules. The code diffs themselves were fine. The problem was that all four agents had fired pnpm install at nearly the same instant and fought over the same store and the same lockfile.

This article is the fix that has kept things stable since. The idea is simple: leave code generation parallel, and serialize exactly one thing — the dependency install.

What Actually Broke — Two Shared Resources

When we think of parallel-agent collisions, we picture two agents editing the same source file. But that was not the failure here. What broke were two resources that agents rarely see.

The first is the pnpm content-addressable store (by default ~/.local/share/pnpm/store or ~/.pnpm-store). pnpm keeps one copy of each package in a central store and hard-links into each project's node_modules. When two processes write to the store at once, one links into a package another is still extracting, leaving a directory with missing contents.

The second is pnpm-lock.yaml. pnpm rewrites the lockfile when resolution changes during an install. Two installs writing it back simultaneously leave a YAML with one side's intermediate state mixed in, and every later resolution inherits the damage.

In my setup, the worktrees were separated with git worktree, but the store and lockfile were still shared. I had isolated the source but not the dependency resolution — I had drawn the parallelism boundary one level too high.

How to Tell It Apart in Logs

The same "install failed" message looks different depending on cause. The signs specific to a parallel race were these.

Observed signWhat it means
`ENOENT` on a path under the storeAnother process linked to a still-extracting copy
`Cannot read properties of undefined (reading 'integrity')`The lockfile lost an integrity hash mid-rewrite
A huge, disordered `git diff` on `pnpm-lock.yaml`Two resolutions interleaved
A solo re-run always succeedsStrong evidence the code is fine and the cause is contention
Empty directories left under `node_modules/.pnpm`An interrupted extraction

That last row was the decisive test. If a solo re-run always passes, it is not a content bug — it is a timing problem. I now treat that observation as my first triage step.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
The exact way parallel agents fight over the pnpm store and lockfile, and how to spot it in logs
A working implementation that keeps code generation parallel while serializing only dependency installs with a file lock
A per-worktree node_modules layout that preserves the shared store, with before/after failure rates (3-of-12 to 0)
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

App Dev2026-07-14
When the Deploy Was Green but Users Still Saw the Old Build: Field Notes on a Gate That Verifies Your Shipped Commit Reached the Edge
When a deploy reports success but production keeps serving the old build, a post-deploy gate that verifies your shipped commit actually reached the edge via a build stamp closes the gap. Field notes with real operational numbers.
App Dev2026-07-10
An Agent's ORM Code Made p95 Five Times Slower — Measuring Query Counts and Blocking Them in CI
N+1 queries slip past code review because the code looks correct. Here is a CI gate that measures query counts and judges them by their slope against input size, with working code and real numbers.
App Dev2026-07-09
Background Refresh May Never Run — Measuring Execution Opportunity and Redesigning Around Freshness
Scheduling a BGTaskScheduler or WorkManager job is a request, not a guarantee. Here is how I instrumented execution opportunity, defined freshness as an SLO with p50 and p90 targets, and rebuilt the update path into three layers that hold up when background work never runs.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →