{"record":{"id":"a31234a3c5700de3","repo":"paperclipai/paperclip","slug":"native-runner-authority-rotation-state-unavailable","errorCode":"native_runner_authority_rotation_state_unavailable","errorMessage":"native_runner_authority_rotation_state_unavailable","messagePattern":"native_runner_authority_rotation_state_unavailable","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/live/runnerd-codex-transport.ts","lineNumber":301,"sourceCode":"    priorIdentity.runnerInstanceId !== desired.runnerInstanceId ||\n    priorIdentity.environmentLeaseId !== desired.environmentLeaseId ||\n    priorIdentity.normalizedSessionId !== desired.normalizedSessionId ||\n    priorIdentity.runId === desired.runId\n  ) {\n    throw new Error(\n      \"PRP recovery identity does not match the durable session binding\",\n    );\n  }\n  const runnerDirectory = resolve(root, \"runner\");\n  const runnerStatePath = resolve(runnerDirectory, \"runner-state.json\");\n  const archive = authorityArchiveDirectory(root, priorIdentity);\n  const archivedControlPlane = resolve(archive, \"control-plane\");\n  const archivedRunnerState = resolve(archive, \"runner-state.json\");\n  const runnerStateSource = existsSync(runnerStatePath)\n    ? runnerStatePath\n    : archivedRunnerState;\n  if (!existsSync(runnerStateSource)) {\n    throw new Error(\"native_runner_authority_rotation_state_unavailable\");\n  }\n  assertRealDirectory(runnerDirectory);\n  const runnerState = readRunnerState(runnerStateSource);\n  if (\n    runnerState.runnerInstanceId !== priorIdentity.runnerInstanceId ||\n    runnerState.environmentLeaseId !== priorIdentity.environmentLeaseId ||\n    runnerState.runId !== priorIdentity.runId ||\n    runnerState.normalizedSessionId !== priorIdentity.normalizedSessionId ||\n    runnerState.turnId !== priorIdentity.turnId ||\n    runnerState.itemId !== priorIdentity.itemId ||\n    runnerState.lifecycle !== \"suspended\"\n  ) {\n    throw new Error(\"native_runner_authority_rotation_requires_settled_state\");\n  }\n  const archivesRoot = resolve(root, \"authority-epochs\");\n  if (existsSync(archivesRoot)) {\n    assertRealDirectory(archivesRoot);\n  } else {","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/live/runnerd-codex-transport.ts#L283-L319","documentation":"rotateLocalAuthorityEpoch() needs a readable runner state to validate before rotating: it uses the live runner-state.json if present, else the archived copy inside the authority epoch archive. If neither file exists it throws native_runner_authority_rotation_state_unavailable — the rotation cannot proceed because there is no prior runner state to validate and archive.","triggerScenarios":"#resume() triggers local rotation while both runner-state.json and the archived runner-state.json (under the authority-epochs archive's control-plane/runners layout) are missing.","commonSituations":"State directory partially cleaned up by an operator or cleanup job; interrupted prior rotation that moved the live file but never archived it; fresh/re-initialized state root that never had runner state; wrong state root configured.","solutions":["Confirm you are pointing at the correct state root (a misconfigured root looks identical to a missing state)","Check for leftover quarantine or partially rotated directories (<root>.quarantine-*, authority-epochs) and restore runner-state.json from them","If state is genuinely absent, re-initialize the runner/session instead of rotating (rotation requires prior state)","Restore from backup of the runner state directory before resuming"],"exampleFix":"// before\npnpm runner resume --state-root data/runner-state  # runner-state.json deleted by cleanup\n// after\nls data/runner-state*/  && find data -name 'runner-state.json'\n# restore from archive/quarantine copy:\ncp data/runner-state.quarantine-<uuid>/runner/runner-state.json data/runner-state/runner/runner-state.json","handlingStrategy":"fallback","validationCode":"import { existsSync } from \"node:fs\";\nfunction hasRunnerState(root: string): boolean {\n  return existsSync(`${root}/runner/runner-state.json`) ||\n    existsSync(`${root}/authority-epochs`); // archives may hold prior state\n}","typeGuard":null,"tryCatchPattern":"try {\n  await transport.resume();\n} catch (err) {\n  if (err.code === \"native_runner_authority_rotation_state_unavailable\") {\n    logger.error(\"no runner-state.json live or archived; re-init required\");\n    reinitializeRunnerState();\n  } else throw err;\n}","preventionTips":["Do not run cleanup jobs against live runner state directories","Verify the state root config before resume","After a failed rotation, reconcile from quarantine/archive copies before retrying","Back up the runner directory before maintenance"],"tags":["filesystem","authority-rotation","state-file","codex"],"backgroundTag":"file-not-found","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}