paperclipai/paperclip · error · Error

Invalid worktree seed manifest at ${manifestPath}: ${error i

Error message

Invalid worktree seed manifest at ${manifestPath}: ${error instanceof Error ? error.message : String(error)}

What it means

readWorktreeSeedManifest() parses the seed manifest JSON next to the worktree config (resolved by resolveWorktreeSeedMarkerPaths). If the file exists but JSON.parse fails, the underlying parse error is wrapped with the manifest path. Manifest writes are atomic (temp file + rename, mode 0600), so corruption is external: manual edits, a non-atomic writer, or truncation.

Source

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

  return nonEmpty(envEntries.PAPERCLIP_INSTANCE_ID)
    ?? sanitizeWorktreeInstanceId(path.basename(path.dirname(path.resolve(configPath))));
}

function writeWorktreeSeedManifest(filePath: string, manifest: WorktreeSeedManifest): void {
  mkdirSync(path.dirname(filePath), { recursive: true });
  const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
  writeFileSync(temporaryPath, `${JSON.stringify(manifest, null, 2)}\n`, { mode: 0o600 });
  renameSync(temporaryPath, filePath);
}

export function readWorktreeSeedManifest(configPath: string): WorktreeSeedManifest | null {
  const manifestPath = resolveWorktreeSeedMarkerPaths(configPath).manifest;
  if (!existsSync(manifestPath)) return null;
  let parsed: unknown;
  try {
    parsed = JSON.parse(readFileSync(manifestPath, "utf8"));
  } catch (error) {
    throw new Error(
      `Invalid worktree seed manifest at ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`,
    );
  }
  const value = parsed as Partial<WorktreeSeedManifest>;
  const diagnosticsValid = Array.isArray(value.diagnostics) && value.diagnostics.every((diagnostic) => (
    diagnostic
    && typeof diagnostic === "object"
    && WORKTREE_SEED_PHASES.includes(diagnostic.phase)
    && ["started", "succeeded", "failed"].includes(diagnostic.status)
    && typeof diagnostic.at === "string"
    && (diagnostic.message === undefined || typeof diagnostic.message === "string")
  ));
  const verifiedTerminalValid = value.state !== "verified" || (
    value.phase === "complete"
    && typeof value.snapshotAt === "string"
    && value.snapshotAt.length > 0
    && typeof value.migrationRevision === "string"
    && value.migrationRevision.length > 0

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Delete the corrupt manifest file (path is in the error) and re-run the seed — it re-provisions from the registered source
  2. Restore the manifest from a worktree backup if seed state must be preserved
  3. Stop hand-editing or externally rewriting seed marker files; they are agent-writable diagnostics only
Defensive patterns

Strategy: fallback

Validate before calling

import { readWorktreeSeedManifest, resolveWorktreeSeedMarkerPaths } from './worktree-lib';

let manifest = null;
try {
  manifest = readWorktreeSeedManifest(configPath);
} catch (error) {
  // corrupt JSON: treat as absent, drop the marker, let the seed re-provision
  rmSync(resolveWorktreeSeedMarkerPaths(configPath).manifest, { force: true });
}

Try / catch

Catch the 'Invalid worktree seed manifest' error, log the wrapped parse error, delete the named file, and re-run ensureWorktreeSeeded.

Prevention

When it happens

Trigger: Any seed operation (ensureWorktreeSeeded, updateWorktreeSeedManifest, startWorktreeSeedAttempt) reading a manifest file whose bytes are not valid JSON — e.g. the file was hand-edited, truncated on crash, or rewritten by tooling that did partial writes.

Common situations: An operator edited the marker JSON to 'fix' a seed state; a disk-full event truncated the file; an external sync tool copied the file mid-write; a different CLI version wrote a format the parser chokes on at the JSON level.

Related errors


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