paperclipai/paperclip · critical
native_runner_state_quarantined
native_runner_state_quarantined
Error message
native_runner_state_quarantined: ${detail}; the prior state was preserved for operator recovery What it means
quarantineLocalRuntimeState() is the last-resort recovery path: when resuming (#resume) finds state it cannot safely load, it renames the entire state root to '<root>.quarantine-<uuid>', creates a fresh 0700 directory, and throws native_runner_state_quarantined with the original cause embedded. The old state is preserved at the quarantine path for operator recovery — nothing is deleted.
Source
Thrown at packages/paperclip-runner/src/live/runnerd-codex-transport.ts:226
}
function assertRealDirectory(path: string): void {
const metadata = lstatSync(path);
if (metadata.isSymbolicLink() || !metadata.isDirectory()) {
throw new Error("native_runner_authority_archive_unsafe");
}
}
function quarantineLocalRuntimeState(root: string, reason: unknown): never {
assertRealDirectory(root);
const quarantine = resolve(
dirname(root),
`${basename(root)}.quarantine-${randomUUID()}`,
);
renameSync(root, quarantine);
mkdirSync(root, { mode: 0o700 });
const detail = reason instanceof Error ? reason.message : String(reason);
throw new Error(
`native_runner_state_quarantined: ${detail}; the prior state was preserved for operator recovery`,
);
}
function authorityArchiveDirectory(
root: string,
identity: DurableRecoveryIdentity,
): string {
const digest = createHash("sha256")
.update(JSON.stringify(identity))
.digest("hex")
.slice(0, 24);
return resolve(root, "authority-epochs", `epoch-${digest}`);
}
function latestArchivedControlPlaneState(
root: string,
desired: DurableRecoveryIdentity,View on GitHub (pinned to 01ad858492)
Solutions
- Read the embedded detail after 'native_runner_state_quarantined:' — it names the original failure
- Recover data from the sibling directory '<root>.quarantine-<uuid>' left next to the state root
- After inspecting/reconciling, delete or move the quarantine directory and restart the runner with fresh state
- Fix the root cause (version mismatch, manual edits, corruption) before resuming again, or it will re-quarantine
Example fix
// before ls data/runner-state # fresh empty dir cp -a data/runner-state.quarantine-<uuid>/control-plane data/runner-state/ // after mv data/runner-state.quarantine-<uuid> data/runner-state.recovered && # reconcile/inspect data/runner-state.recovered, then re-init data/runner-state cleanly
Defensive patterns
Strategy: try-catch
Validate before calling
import { existsSync, readdirSync } from "node:fs";
function findQuarantines(root: string): string[] {
return existsSync(root) ? readdirSync(root, { withFileTypes: false })
.filter((n) => n.startsWith(".quarantine-")) : [];
} Try / catch
try {
await transport.resume();
} catch (err) {
if (String(err.message).startsWith("native_runner_state_quarantined:")) {
const cause = String(err.message).split(":")[1];
logger.error("runner state quarantined; original cause:", { cause });
inspectQuarantineDirAndReinit();
} else throw err;
} Prevention
- Never hand-edit runner state files
- Pin a compatible runner version for the state schema in use
- Back up the state root before upgrades
- On resume failure, read the embedded cause in the quarantine error before restarting
When it happens
Trigger: #resume() encounters a state-loading/validation error (e.g. unsafe or unparseable state files) that makes continuing unsafe, triggering quarantine of the runtime state root before throwing.
Common situations: Corrupted or hand-edited state after a crash; state written by an incompatible runner version; operator experimentation with the state directory mid-run; disk-level corruption.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- codex auth cache: account_id is not a valid account handle
- codex auth cache: account-home directory no longer exists; r
- persisted Codex ACPX resultless recovery requires a complete
- Codex working directory must exist before provider admission
- codex_startup_trust_cannot_preserve_configuration
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/a1a0270e551404ee.
Report an issue: GitHub.