paperclipai/paperclip · error
native_runner_control_plane_state_unsafe
native_runner_control_plane_state_unsafe
Error message
native_runner_control_plane_state_unsafe
What it means
readControlPlaneState() validates the on-disk control-plane state file with lstatSync before reading it. It refuses to load anything that is a symlink, not a regular file, or larger than 64 MiB, throwing native_runner_control_plane_state_unsafe. This is a tamper/safety guard: the control-plane state drives authority and resume decisions, so an unexpected file shape must not be trusted or parsed.
Source
Thrown at packages/paperclip-runner/src/live/runnerd-codex-transport.ts:158
export function withCodexCollaborationRuntimeInstructions(
instructions: string,
enabled = true,
): string {
if (!enabled) return instructions;
const base = instructions.trimEnd();
return `${base}\n\n${CODEX_COLLABORATION_RUNTIME_INSTRUCTIONS}`;
}
function readControlPlaneState(directory: string): Record<string, unknown> {
const path = resolve(directory, "control-plane-state.json");
const metadata = lstatSync(path);
if (
metadata.isSymbolicLink() ||
!metadata.isFile() ||
metadata.size > 64 * 1024 * 1024
) {
throw new Error("native_runner_control_plane_state_unsafe");
}
return record(JSON.parse(readFileSync(path, "utf8")));
}
function readRunnerState(path: string): Record<string, unknown> {
const metadata = lstatSync(path);
if (
metadata.isSymbolicLink() ||
!metadata.isFile() ||
metadata.size > 16 * 1024 * 1024
) {
throw new Error("native_runner_authority_rotation_state_unsafe");
}
return record(JSON.parse(readFileSync(path, "utf8")));
}
function controlPlaneIdentity(
state: Record<string, unknown>,View on GitHub (pinned to 01ad858492)
Solutions
- Inspect the file: `ls -la` the path; replace any symlink with a real regular file
- Check file size (`stat -c %s`); if over 64 MiB, restore state from a valid backup or re-initialize the runner state directory
- If the state directory is corrupted, let the quarantine/re-init path recreate it rather than hand-editing the file
- Verify the runner is pointed at the correct state root (config mistake can make it read a foreign file)
Example fix
// before
const state = transport.state; // throws native_runner_control_plane_state_unsafe
// after
import { statSync } from "node:fs";
const meta = statSync(controlPlaneStatePath);
if (meta.isFile() && meta.size <= 64 * 1024 * 1024 && !lstatSync(controlPlaneStatePath).isSymbolicLink()) {
const state = transport.state;
} Defensive patterns
Strategy: validation
Validate before calling
import { lstatSync, statSync } from "node:fs";
function isSafeStateFile(p: string): boolean {
const m = lstatSync(p);
return !m.isSymbolicLink() && statSync(p).isFile() && m.size <= 64 * 1024 * 1024;
} Try / catch
try {
const state = transport.state;
} catch (err) {
if (err.code === "native_runner_control_plane_state_unsafe") {
logger.error("control-plane state file unsafe; restore from backup", { path });
await recoverFromQuarantineOrReinit();
} else throw err;
} Prevention
- Never symlink runner state files; configure the state root as a real directory
- Exclude state directories from cloud-sync/backup tools that create links or grow files
- Monitor state file size; alert before the 64 MiB cap
- Run the runner with correct state-root config to avoid reading foreign files
When it happens
Trigger: The control-plane state path is a symlink, a socket/directory/device instead of a regular file, or has grown beyond the 64 MiB cap when state(), archivedIdentity(), or #resume reads it.
Common situations: Operator replaced the state file with a symlink into a mount; a runaway writer corrupted/blew up the state file; running the runner against a bind-mounted or container-virtualized path where lstat attributes differ.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- native_runner_authority_rotation_state_unsafe
- native_runner_authority_archive_unsafe
- native_runner_authority_rotation_state_unavailable
- codex auth cache: account_id is not a valid account handle
- codex auth cache: account-home directory no longer exists; r
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/3af1c1a634da060d.
Report an issue: GitHub.