paperclipai/paperclip · error
native_runner_authority_archive_unsafe
native_runner_authority_archive_unsafe
Error message
native_runner_authority_archive_unsafe
What it means
assertRealDirectory() verifies that a required state-root path (runtime state root, archive directory, control-plane dir, or maintenance state dir) is a real directory and not a symlink, using lstatSync. It throws native_runner_authority_archive_unsafe when the path is missing as a directory, is a symlink, or is a regular file. This prevents authority rotation and quarantine operations from following links or operating on unexpected file types.
Source
Thrown at packages/paperclip-runner/src/live/runnerd-codex-transport.ts:213
}
function assertSuspendedRunnerState(
state: Record<string, unknown>,
expected: DurableRecoveryIdentity,
): void {
if (
state.schema !== "paperclip.runner.durable.state.v1" ||
!recoveryIdentityMatches(state, expected) ||
state.lifecycle !== "suspended"
) {
throw new Error("native_runner_authority_rotation_requires_settled_state");
}
}
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(View on GitHub (pinned to 01ad858492)
Solutions
- Run `ls -la` on the configured state root; replace symlinks with real directories (or copy contents into a real directory)
- Recreate the missing directory with `mkdir -p` and correct ownership/permissions (0700)
- Fix the runner state-root configuration to point at an actual directory
- If the layout is unrecoverable, move the directory aside and let the runner re-initialize fresh state
Example fix
// before PAPERCLIP_RUNNER_STATE_ROOT=~/dotfiles/runner-state # symlink // after mkdir -p ~/var/paperclip/runner-state && cp -a ~/dotfiles/runner-state/. ~/var/paperclip/runner-state/ PAPERCLIP_RUNNER_STATE_ROOT=~/var/paperclip/runner-state
Defensive patterns
Strategy: validation
Validate before calling
import { lstatSync } from "node:fs";
function isRealDirectory(p: string): boolean {
try {
const m = lstatSync(p);
return m.isDirectory();
} catch { return false; }
} Try / catch
try {
runner.start();
} catch (err) {
if (err.code === "native_runner_authority_archive_unsafe") {
logger.error("state root is not a real directory (symlink/file/missing)", { path });
recreateStateRoot();
} else throw err;
} Prevention
- Pre-create the state root as a real directory with mode 0700
- Avoid symlinked paths (dotfile managers, mounts) for state roots
- Smoke-check the state root layout before starting/resuming the runner
- In containers, use plain bind mounts of real directories
When it happens
Trigger: quarantineLocalRuntimeState, latestArchivedControlPlaneState, rotateLocalAuthorityEpoch, rotateExternalAuthorityEpoch, or readMaintenanceState is given a path that is a symlink, a plain file, or not a directory at all.
Common situations: State root configured to a symlinked path (common with dotfile managers or mounted volumes); someone replaced the state directory with a file; the directory was deleted while the runner was down; tmpfs/bind-mount layouts in containers.
Related errors
- native_runner_control_plane_state_unsafe
- native_runner_authority_rotation_state_unsafe
- codex auth cache: account_id is not a valid account handle
- codex auth cache: account-home directory no longer exists; r
- Materialized OpenCode executable has unsafe permissions
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/e0c2f1a97440d98e.
Report an issue: GitHub.