paperclipai/paperclip · error · Error
Worktree seed source diagnostics changed while waiting for…
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.
Solutions
- Ensure a single seed source per worktree: stop the competing service/process, then retry the seed
- If the legacy pending marker is definitively stale (no other seed running), remove it and re-run ensureWorktreeSeeded
- 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
- Ensure exactly one seed source and one seed process per worktree
- Serialize ensure-seeded invocations behind your own lock if multiple services share a worktree
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
- Failed to create a pending worktree seed manifest.
- Cannot seed target embedded PostgreSQL at
- Invalid worktree seed manifest at
- Invalid worktree seed manifest at
- Worktree seed manifest does not exist at
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-21).
Data as JSON: /api/errors/1f695a1af42a5db1.
Report an issue: GitHub.
Appendix: source
Thrown at cli/src/commands/worktree.ts:2295
// 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 01ad858492)