paperclipai/paperclip · error · Error

Worktree seed source diagnostics changed while waiting for t

Error message

Worktree seed source diagnostics changed while waiting for the seed lock.

What it means

ensureWorktreeSeeded reads the legacy pending marker before acquiring the seed lock; under the lock it re-reads it and verifies the sourceConfigPath is unchanged. The lock is a polled cross-process lock (WORKTREE_SEED_LOCK_POLL_MS = 50), and this check detects that another actor rewrote the legacy source diagnostics while this process waited — i.e. two seed processes with different sources are racing on one worktree.

Source

Thrown at cli/src/commands/worktree.ts:2334

  // Resolve all authority-bearing paths before creating the lock. The manifest is
  // agent-writable diagnostic evidence and never selects the source. A stale source
  // diagnostic is replaced under the lock from this server/operator registration.
  let canonicalSource = registeredSeedSource;
  mkdirSync(path.dirname(markers.lock), { recursive: true });
  const releaseLock = await acquireWorktreeSeedLock(markers.lock);
  try {
    // These checks deliberately happen under the cross-process lock. A second
    // service process waits for the first seed transaction, then observes the
    // verified manifest instead of cloning the same database concurrently.
    let manifest = readWorktreeSeedManifest(configPath);
    if (manifest?.state === "verified") {
      return { seeded: false, reason: "verified_manifest" };
    }
    if (!manifest && existsSync(markers.pending)) {
      const currentLegacyPending = readLegacyWorktreeSeedPendingMarker(markers.pending);
      if (currentLegacyPending.sourceConfigPath !== legacyPending?.sourceConfigPath) {
        throw new Error("Worktree seed source diagnostics changed while waiting for the seed lock.");
      }
      markWorktreeSeedPending({
        configPath,
        sourceConfigPath: registeredSeedSource.configPath,
        targetInstanceId: targetPaths.instanceId,
        seedMode: "minimal",
        diagnosticMessage: "Re-derived seed source diagnostics from the registered canonical source.",
      });
      manifest = readWorktreeSeedManifest(configPath);
    }
    if (!manifest) {
      const legacyEvidence = await (
        dependencies.inspectLegacyDatabase ?? inspectLegacyWorktreeDatabase
      )(configPath);
      if (legacyEvidence) {
        markWorktreeSeedPending({
          configPath,
          sourceConfigPath: registeredSeedSource.configPath,

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Ensure a single seed source per worktree: stop the competing service/process, then retry the seed
  2. If the legacy pending marker is definitively stale (no other seed running), remove it and re-run ensureWorktreeSeeded
  3. Re-register the worktree with one canonical source before seeding again
Defensive patterns

Strategy: retry

Try / catch

for (let attempt = 0; attempt < 2; attempt++) {
  try {
    return await ensureWorktreeSeeded(opts);
  } catch (error) {
    if (!String(error).includes('source diagnostics changed')) throw error;
    await stopCompetingSeedActors();
  }
}

Prevention

When it happens

Trigger: Two concurrent seed invocations with different registered/explicit sources for the same worktree: the first holds the lock and mutates legacy diagnostics; the second acquires the lock afterward and sees a different sourceConfigPath than its pre-lock read.

Common situations: Two services or terminals seeding the same worktree from different sources; a re-registration pointing at a new source while an old seed was still queued; automation overlapping ensure-seeded runs.

Related errors


AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-21). Data as JSON: /api/errors/1f695a1af42a5db1. Report an issue: GitHub.