#381 swamp CLI commands fail silently or hang when invoked from git worktrees via SWAMP_REPO_DIR
Opened by mgreten · 5/20/2026· Shipped 5/20/2026
Description
When an agentic pipeline creates a git worktree (e.g. git worktree add trees/my-feature) and invokes swamp commands from inside that worktree using SWAMP_REPO_DIR pointing to the main checkout, several commands fail or hang:
swamp model method runhangs indefinitely (0% CPU, active TCP connection to nothing)swamp extension fmt <path>errors with YAML parse failures when the extension source file exists only in the worktree (not in the main repo's.swamp/cache)swamp model createandswamp model type describefail because the extension bundle isn't available in the worktree's context
Environment
- swamp
20260516.045246.0-sha.e6eda98d - macOS Darwin 25.3.0, ARM64
- Git worktrees created by an automated pipeline that runs
git worktree add trees/<session-id>from the main repo
Architecture
Our setup uses a single swamp repo (~/git/tooling-repo) as the control plane for multiple target projects. We don't initialize swamp in the target project repos yet — the tooling and workflows aren't battle-tested enough to introduce to the wider team. The same goes for the prompt/config management approach: a secondary repo holds project-specific configs (e.g. adw.yml) that get synced into target repos via a script. Until the patterns are proven, the swamp files and workflow stay isolated in the tooling repo.
The pipeline works like this:
- A prompt/config repo contains project-specific configs (e.g.
adw.yml) that get synced into target project repos via a sync script - The agentic pipeline runs from the tooling repo and creates git worktrees for isolation:
git worktree add trees/<session-id> - Build agents inside the worktree invoke swamp commands via
SWAMP_REPO_DIR=~/git/tooling-repo swamp model method run ... - Extension model source files (
.ts) are created by the build agent inside the worktree atextensions/models/my_model.ts
Steps to Reproduce
- Initialize swamp in a repo:
swamp init - Create a local extension model at
extensions/models/example.ts - Run
swamp extension install(registers the model type) - Create a git worktree:
git worktree add trees/test-branch - From the worktree, try:
SWAMP_REPO_DIR=<main-repo-path> swamp model method run example invoke --json - Also try:
swamp extension fmt extensions/models/example.tsfrom inside the worktree
Expected: Commands work the same as from the main checkout since SWAMP_REPO_DIR points to the initialized repo.
Actual:
swamp model method runhangs indefinitely — the Deno runtime starts but never completesswamp extension fmtfails withSyntaxError: Cannot read documentwhen it tries to parse the.tsfile as YAML, or when the extension source only exists in the worktree (not in.swamp/cache)
Impact
This blocks any pipeline that uses git worktrees for branch isolation (a common pattern for automated code generation pipelines that need to work on feature branches without dirtying the main checkout). We had to remove all swamp CLI invocations from our pipeline's acceptance criteria and defer them to post-merge manual steps.
Possible Root Causes
- Lock contention —
swamp model method runacquires a per-model lock. If the worktree'sSWAMP_REPO_DIRresolves to a different filesystem path than expected, the lock may never be acquired or released. - Extension bundle cache miss —
.swamp/stores compiled extension bundles. When the source.tsfile exists in the worktree but the bundle was compiled from the main checkout, the paths don't match and the runtime can't find the bundle. swamp extension fmtpath resolution — The command expects a manifest.yaml or directory path, but when given a.tsfile path from a worktree, it may resolve relative to the wrong root.
Workaround
Don't run swamp CLI commands from git worktrees. Only invoke them from the main checkout after changes are merged or cherry-picked back. For automated pipelines, mark swamp-dependent verification steps as post-merge tasks.
Question
Would initializing swamp directly in the target project repo (instead of using a separate control-plane repo with SWAMP_REPO_DIR) resolve the worktree issue? Or does the .swamp/ cache have the same path-resolution problem regardless of where swamp init was run?
Shipped
Click a lifecycle step above to view its details.
mgreten commented 5/20/2026, 2:56:26 AM
Clarification on the workaround section: "defer to post-merge" effectively means skip all validation. Here's what doesn't run:
swamp extension fmt— model TypeScript never gets formatted or validated pre-merge. Unformatted code lands on main.swamp extension quality— the 12-point quality scorecard never runs. Quality issues discovered only after merge.swamp model create— the model instance YAML is never generated. After merge, someone must manually runswamp model createbefore the model is usable.swamp model method run(smoke test) — the preflight/execution check that proves the model actually works never fires. Broken model code can merge silently.
This isn't a viable workaround for any pipeline that depends on swamp for pre-merge validation. The worktree incompatibility effectively makes swamp a post-hoc audit tool rather than a CI gate, which undermines the value of structured model validation.
mgreten commented 5/20/2026, 4:50:34 AM
Update: this is mostly resolved on our end via worktree-side swamp extension install, with one caveat about lock contention that I split into a separate issue (#382).
What worked
The fix is to run swamp extension install from inside the worktree right after git worktree add succeeds, so the worktree's own .swamp/ cache (bundles, pulled extensions) gets populated. .swamp.yaml is already git-tracked so it travels with the checkout; only .swamp/ is gitignored and starts empty.
We wired this into our worktree adapter as a post-creation step. Once the cache exists, the original symptoms are all gone:
swamp model method runno longer hangs — verified by runningswamp model method run blinc-qa-runner invoke --prNumber 99999 --jsonfrom inside an ADW worktree end-to-end in a live pipeline run; the call returnedstatus: "skipped"as expected (preflight failure) without hanging.swamp model create @matg/blinc-qa-runner blinc-qa-runner-testsucceeds (exit 0) inside the worktree — instance YAML written tomodels/@matg/blinc-qa-runner/.swamp model type describe @matg/blinc-qa-runner --jsonreturns the full schema.
So the underlying claim "swamp commands fail or hang inside a worktree" is actually a single-cause problem: the worktree starts with no .swamp/ cache, and that's all swamp needs.
Recommendation for users hitting this
If you're using git worktrees with swamp, add swamp extension install to your worktree-creation flow. We did it in Ruby (Open3.capture3("swamp", "extension", "install", chdir: worktree_path)), but a one-line shell hook would work too.
Caveat — datastore lock contention
While integrating this, we hit a separate problem: swamp extension install itself contends on .datastore.lock against any concurrent swamp model method run on the same datastore. In our setup (two machines running scheduled models against a shared MinIO datastore) the lock was held nearly continuously, so every install hit a 60s LockTimeoutError.
The retry workaround (sleep 30s, retry once) is reliable in practice — both pipeline runs we did succeeded on the retry — but the underlying lock model is broader than this specific worktree case. I filed that separately as #382 with the source-level analysis.
What's NOT solved by swamp extension install
One thing in the original report I never reproduced cleanly: a parseExtensionManifest YAML parse error when fmt was pointed at the local .ts file. On further investigation, that's expected — swamp extension fmt requires a manifest.yaml path and is for published extensions only, not local @matg/ source files. We dropped that AC from our plan rather than treating it as a swamp bug; if there's a fmt path for local-only extensions, that might be its own feature request.
Feel free to close this if swamp extension install covers the symptom for everyone else hitting it.
mgreten commented 5/21/2026, 2:22:26 PM
Thank you for the rapid fix here. That is amazing! Well done team. Thank you!
Sign in to post a ripple.