paperclipai/paperclip · error

native_runner_authority_archive_incomplete

native_runner_authority_archive_incomplete

Error message

native_runner_authority_archive_incomplete

What it means

After renaming the active control-plane directory and the runner state file into the archive, rotateLocalAuthorityEpoch verifies that both archived paths exist. If either rename silently failed or the source paths were missing, the durable transaction marker is incomplete, so the function throws this error. This is a post-condition check guaranteeing the archive is recoverable before the rotation returns.

Source

Thrown at packages/paperclip-runner/src/live/runnerd-codex-transport.ts:343

    mkdirSync(archive, { mode: 0o700 });
  }
  assertRealDirectory(archive);
  const activeControlPlane = resolve(root, "control-plane");
  if (existsSync(activeControlPlane)) {
    assertRealDirectory(activeControlPlane);
    if (existsSync(archivedControlPlane)) {
      throw new Error("native_runner_authority_archive_conflict");
    }
    renameSync(activeControlPlane, archivedControlPlane);
  }
  if (existsSync(runnerStatePath)) {
    if (existsSync(archivedRunnerState)) {
      throw new Error("native_runner_authority_archive_conflict");
    }
    renameSync(runnerStatePath, archivedRunnerState);
  }
  if (!existsSync(archivedControlPlane) || !existsSync(archivedRunnerState)) {
    throw new Error("native_runner_authority_archive_incomplete");
  }
  return controlPlaneState;
}

async function rotateExternalAuthorityEpoch(
  root: string,
  controlPlaneState: Record<string, unknown>,
  desired: DurableRecoveryIdentity,
  readRunnerState: () => Promise<Record<string, unknown>>,
  archiveRunnerState: (input: {
    archiveKey: string;
    priorIdentity: DurableRecoveryIdentity;
  }) => Promise<Record<string, unknown>>,
): Promise<Record<string, unknown>> {
  const priorIdentity = controlPlaneIdentity(controlPlaneState);
  if (
    priorIdentity.runnerInstanceId !== desired.runnerInstanceId ||
    priorIdentity.environmentLeaseId !== desired.environmentLeaseId ||

View on GitHub (pinned to 01ad858492)

Solutions

  1. Inspect the root directory and confirm which of control-plane / runner state exists actively vs archived
  2. Restore the missing source file from backup or let the controller re-create it, then retry the rotation
  3. Check filesystem health/mount type if renames report success but files are missing
  4. Avoid sharing the same data root across concurrent runnerd processes
Defensive patterns

Strategy: try-catch

Validate before calling

if (!existsSync(activeControlPlanePath) || !existsSync(runnerStatePath)) {
  throw new Error("active authority files missing; rotation would produce an incomplete archive");
}

Type guard

const hasCompleteActiveAuthority = (root: string) =>
  existsSync(resolve(root, "control-plane")) && existsSync(resolve(root, "runner-state"));

Try / catch

try {
  rotateLocalAuthorityEpoch(root, desired);
} catch (err) {
  if ((err as Error).message === "native_runner_authority_archive_incomplete") {
    restoreAuthorityFromBackup(root); // or rebuild state
  } else throw err;
}

Prevention

When it happens

Trigger: Calling rotateLocalAuthorityEpoch when, after the rename steps, either the archived control-plane directory or the archived runner-state file does not exist on disk — typically because the source path was absent (renameSync skipped or failed) or the filesystem operation failed silently.

Common situations: External deletion of active control-plane/runner-state files between checks and renames; network/overlay filesystems where renames are unreliable; a partially cleaned data root missing one of the two active paths; a prior crash left the root in a half-rotated state.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/9ec29a828382c784. Report an issue: GitHub.