thedotmack/claude-mem · warning

Worktree adoption skipped branch

Error message

Worktree adoption skipped branch

What it means

Worktree adoption wraps per-worktree adoption in one SQLite transaction, with each branch adopted inside its own try/catch via adoptWorktreeInTransaction. When a single worktree fails (bad metadata, constraint violation, or statements failing because the shared transaction already aborted), this warning records the worktree path and error into result.errors and continues. Under dryRun, all changes still roll back by design via DryRunRollback.

Source

Thrown at src/services/infrastructure/WorktreeAdoption.ts:283

        sumChanges = updateSum.run(parentProject, worktreeProject).changes;
      }
      for (const r of rows) {
        adoptedChromaTargets.push({ docType: 'observation', sqliteId: r.id });
      }
      for (const r of summaryRows) {
        adoptedChromaTargets.push({ docType: 'session_summary', sqliteId: r.id });
      }
      result.adoptedObservations += obsChanges;
      result.adoptedSummaries += sumChanges;
    };

    const tx = db.transaction(() => {
      for (const wt of targets) {
        try {
          adoptWorktreeInTransaction(wt);
        } catch (err) {
          const message = err instanceof Error ? err.message : String(err);
          logger.warn('SYSTEM', 'Worktree adoption skipped branch', {
            worktree: wt.path,
            branch: wt.branch,
            error: message
          });
          result.errors.push({ worktree: wt.path, error: message });
        }
      }
      if (dryRun) {
        throw new DryRunRollback();
      }
    });

    try {
      tx();
    } catch (err) {
      if (err instanceof DryRunRollback) {
        // Rolled back as intended for dry-run — counts are still useful.
      } else if (err instanceof Error) {

View on GitHub (pinned to e2d1df569a)

Solutions

  1. Read result.errors — each entry pairs the failing worktree path with the underlying message; fix the first entry's cause first.
  2. Re-run adoption: per-branch failures are non-fatal and idempotent re-runs usually clear transient ones.
  3. If every branch fails with transaction-level errors, one early failure poisoned the transaction — resolve that branch or exclude it.
  4. Remember dry runs roll back everything by design; only non-dry runs persist adoptions.
Defensive patterns

Strategy: fallback

Validate before calling

// dry-run first: surface per-branch errors without writing anything
const dry = await adoptMergedWorktrees({ repoPath, dataDirectory, dryRun: true });
if (dry.errors.length > 0) {
  reportAndFix(dry.errors); // address the first entry before the real run
}

Prevention

When it happens

Trigger: Inside the transaction, adopting one worktree throws: unexpected row shape in the worktree's data, UNIQUE constraint on re-adoption of already-adopted rows, or SQLite errors cascading after an earlier statement poisoned the transaction.

Common situations: Re-running adoption over partially adopted data; worktrees with unusual branch names or detached HEAD; a concurrent writer aborting the shared transaction so every subsequent statement fails.

Related errors


AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20). Data as JSON: /api/errors/7e12909216dbb2ee. Report an issue: GitHub.