paperclipai/paperclip · error · Error

Workspace reseed returned without a verified terminal manife

Error message

Workspace reseed returned without a verified terminal manifest.

What it means

Thrown after the reseed CLI exits 0 but the seed manifest on disk is not a verified terminal manifest (isVerifiedWorktreeSeedManifest returns false at server/src/routes/execution-workspaces.ts:785). A successful repair must end with a manifest in the verified terminal state; exit code 0 without it means the CLI never completed verification — typically a stale manifest from a previous attempt, an older CLI that does not write the verified state, or the manifest being rewritten concurrently. The worktree is preserved and the operation is marked failed.

Source

Thrown at server/src/routes/execution-workspaces.ts:786

              }
              await reportProgress({
                metadata: { seedFailurePhase },
                system: seedFailurePhase ? `Workspace seed failed during ${seedFailurePhase}.\n` : null,
              });
              throw new Error(
                repairCommandTimedOut
                  ? `Workspace database repair command timed out during ${repairPhase}.`
                  : `Workspace database repair command failed during ${repairPhase}.`,
              );
            }
            if (!reseedObserved) {
              await reportRepairPhase("target_backup", "succeeded");
              await reportRepairPhase("full_reseed", "started");
            }

            const manifest = JSON.parse(readFileSync(manifestPath, "utf8")) as Record<string, unknown>;
            if (!isVerifiedWorktreeSeedManifest(manifest)) {
              throw new Error("Workspace reseed returned without a verified terminal manifest.");
            }
            const expectedInstanceId = resolveManagedWorkspaceInstanceId(workspaceCwd);
            if (manifest.targetInstanceId !== expectedInstanceId) {
              throw repairPreconditionError(
                422,
                "seed_manifest_instance_mismatch",
                "Verified seed manifest belongs to a different workspace instance.",
              );
            }
            resolveCanonicalWorktreeSeedSource({
              registeredBaseWorkspaceCwd: baseWorkspaceCwd,
              explicitSourceConfigPath: resolveFallbackSeedSourceConfigPath(baseWorkspaceCwd),
              targetConfigPath: path.join(workspaceCwd, ".paperclip", "config.json"),
              expectedTargetInstanceId: repairSeedSource.targetInstanceId,
              manifestSource: manifest.source as { configPath?: unknown; instanceId?: unknown } | undefined,
              manifestTargetInstanceId: manifest.targetInstanceId,
            });
            await reportRepairPhase("full_reseed", "succeeded");

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Confirm the base workspace CLI version matches the server's expectation — update the base checkout (git pull + pnpm install + build) so the CLI writes the verified terminal manifest.
  2. Inspect <worktree>/.paperclip/seed-manifest.json: check state and attemptId — if it is the pre-repair attempt, the child did no work; investigate its stdout in the operation record.
  3. Delete the stale seed-manifest.json (the worktree files and backup are preserved) and re-run repair so a fresh attempt writes a new manifest.
  4. If it recurs, capture the exact manifest JSON and check isVerifiedWorktreeSeedSource's required fields against it.
Defensive patterns

Strategy: try-catch

Validate before calling

import { readFileSync, unlinkSync } from "node:fs";
const manifestPath = path.join(ws.cwd, ".paperclip", "seed-manifest.json");
const m = JSON.parse(readFileSync(manifestPath, "utf8"));
if (m?.state !== "verified") { unlinkSync(manifestPath); } // force a fresh attempt manifest before repair

Type guard

function isVerifiedManifest(m: unknown): boolean {
  const x = m as { state?: unknown; attemptId?: unknown; targetInstanceId?: unknown };
  return x?.state === "verified" && typeof x?.attemptId === "string" && typeof x?.targetInstanceId === "string";
}

Try / catch

try { await repair(id); } catch (err) { if (/verified terminal manifest/.test(String(err?.body?.error ?? ""))) { await removeFile(path.join(cwd, ".paperclip", "seed-manifest.json")); await repair(id); } else throw err; }

Prevention

When it happens

Trigger: POST repair where the child exits 0 but seed-manifest.json is stale (attemptId unchanged from repairPreviousAttemptId, state not verified), was deleted between exit and read, or was written by an older/newer CLI with a different manifest shape that fails the verified-manifest type check.

Common situations: Version skew between the server and the base workspace CLI (cli/dist or tsx entry from an older checkout that exits 0 without writing the verified terminal manifest); a no-op reseed that saw nothing to do and skipped verification; leftover manifest from an earlier failed repair that the child never replaced; antivirus/editor temporarily locking the file on read.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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