paperclipai/paperclip · error

native_runner_authority_rotation_seed_unavailable

native_runner_authority_rotation_seed_unavailable

Error message

native_runner_authority_rotation_seed_unavailable

What it means

rotatedRunAttachPayload needs a seed run-attach/prepare payload (provider configuration) to retarget onto the new epoch. It looks for a persisted template and a command seed; if neither contains a provider field, there is no basis for constructing the rotated attach payload, so it throws this error. Without the seed, the library refuses to fabricate runner configuration.

Solutions

  1. Ensure a run.prepare/run.attach command with a provider payload was recorded before attempting rotation
  2. Restore the persisted template or command seed from backup or from the archived control-plane state
  3. Re-create the runner session from scratch if no durable seed ever existed (rotation is not applicable)
  4. Verify the command-log filter conditions (type run.prepare/run.attach, provider defined) are not excluding your stored commands due to version changes

Example fix

// before
const payload = rotatedRunAttachPayload(...); // throws when no seed provider
// after
const seed = findRunAttachSeed(commands);
if (!seed || seed.payload.provider === undefined) {
  throw new SkipRotationError("no attach seed; resume without epoch rotation");
}
const payload = rotatedRunAttachPayload(...);
Defensive patterns

Strategy: validation

Validate before calling

const seed = persistedTemplate ?? record(commandSeed?.payload);
if (seed?.provider === undefined) {
  throw new Error("no run.prepare/run.attach seed with provider persisted; rotation unavailable");
}

Type guard

const hasAttachSeed = (cmd?: { type: string; payload: unknown }) =>
  cmd != null && (cmd.type === "run.prepare" || cmd.type === "run.attach") &&
  typeof cmd.payload === "object" && cmd.payload !== null &&
  (cmd.payload as Record<string, unknown>).provider !== undefined;

Try / catch

try {
  payload = rotatedRunAttachPayload(...);
} catch (err) {
  if ((err as Error).message === "native_runner_authority_rotation_seed_unavailable") {
    return resumeWithoutRotation(); // re-create session instead
  } else throw err;
}

Prevention

When it happens

Trigger: Calling rotatedRunAttachPayload (via runAttachTemplate) when no persisted template exists and no run.prepare/run.attach command in the seed has a defined provider field — e.g., rotation is attempted before the runner ever persisted its attach configuration.

Common situations: Resuming a runner whose initial run.prepare command was never durably recorded; a data root where control-plane state was archived/removed before the template was written; invoking authority rotation on a freshly created session with no prior attach command; truncation or corruption of the command log.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-10). Data as JSON: /api/errors/48468da7bdf16765. Report an issue: GitHub.

Appendix: source

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

  const commands = Array.isArray(state.commands)
    ? state.commands.map(record)
    : [];
  const persistedTemplate =
    state.runAttachTemplate !== null &&
    typeof state.runAttachTemplate === "object" &&
    !Array.isArray(state.runAttachTemplate)
      ? (state.runAttachTemplate as Record<string, unknown>)
      : null;
  const commandSeed = [...commands]
    .reverse()
    .find(
      (command) =>
        (command.type === "run.prepare" || command.type === "run.attach") &&
        record(command.payload).provider !== undefined,
    );
  const seed = persistedTemplate ?? record(commandSeed?.payload);
  if (seed.provider === undefined)
    throw new Error("native_runner_authority_rotation_seed_unavailable");
  return retargetRunAttachPayload(
    seed,
    desired,
    authorizedTools,
    completionContract,
  );
}

function retargetRunAttachPayload(
  seedPayload: Record<string, unknown>,
  desired: DurableRecoveryIdentity,
  authorizedTools: Record<string, unknown> | null,
  completionContract:
    { revision: string; criterionIds: readonly string[] } | undefined,
): Record<string, unknown> {
  const payload = structuredClone(seedPayload);
  const provider = record(payload.provider);
  if (provider.kind === "acpx" || provider.provider === "acpx") {

View on GitHub (pinned to 3f1d897a7c)