Skip to main content
← Back to list
01Issue
BugShippedSwamp CLI
Assigneesstack72

#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 run hangs 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 create and swamp model type describe fail 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:

  1. A prompt/config repo contains project-specific configs (e.g. adw.yml) that get synced into target project repos via a sync script
  2. The agentic pipeline runs from the tooling repo and creates git worktrees for isolation: git worktree add trees/<session-id>
  3. Build agents inside the worktree invoke swamp commands via SWAMP_REPO_DIR=~/git/tooling-repo swamp model method run ...
  4. Extension model source files (.ts) are created by the build agent inside the worktree at extensions/models/my_model.ts

Steps to Reproduce

  1. Initialize swamp in a repo: swamp init
  2. Create a local extension model at extensions/models/example.ts
  3. Run swamp extension install (registers the model type)
  4. Create a git worktree: git worktree add trees/test-branch
  5. From the worktree, try: SWAMP_REPO_DIR=<main-repo-path> swamp model method run example invoke --json
  6. Also try: swamp extension fmt extensions/models/example.ts from 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 run hangs indefinitely — the Deno runtime starts but never completes
  • swamp extension fmt fails with SyntaxError: Cannot read document when it tries to parse the .ts file 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

  1. Lock contentionswamp model method run acquires a per-model lock. If the worktree's SWAMP_REPO_DIR resolves to a different filesystem path than expected, the lock may never be acquired or released.
  2. Extension bundle cache miss.swamp/ stores compiled extension bundles. When the source .ts file 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.
  3. swamp extension fmt path resolution — The command expects a manifest.yaml or directory path, but when given a .ts file 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?

02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 12 MOREREVIEW+ 3 MOREPR_MERGEDSHIPPED

Shipped

5/20/2026, 4:00:13 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack725/20/2026, 6:57:36 AM
Editable. Press Enter to edit.

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 run swamp model create before 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 run no longer hangs — verified by running swamp model method run blinc-qa-runner invoke --prNumber 99999 --json from inside an ADW worktree end-to-end in a live pipeline run; the call returned status: "skipped" as expected (preflight failure) without hanging.
  • swamp model create @matg/blinc-qa-runner blinc-qa-runner-test succeeds (exit 0) inside the worktree — instance YAML written to models/@matg/blinc-qa-runner/.
  • swamp model type describe @matg/blinc-qa-runner --json returns 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.