paperclipai/paperclip · error · Error

Paperclip returned no result while

Error message

Paperclip returned no result while ${action}.

What it means

Thrown when a PRP run rotation must be performed without an exact authority match and with no warm recovery available, but the local control-plane state needed to rotate the local authority epoch is missing — either there is no local provider or the tracked controlPlaneState is null. The library cannot rotate an authority epoch from nothing, so it throws.

Solutions

  1. Ensure the local provider is enabled and that control-plane state was loaded before reaching the rotation step.
  2. Use warm recovery (a valid recovery proof/receipt) so the exact-authority path or warm-recovery path can be taken instead of local rotation.
  3. Restore or regenerate the runner's persisted control-plane state so controlPlaneState is non-null at rotation time.

Example fix

// before
// rotation attempted with no prior state loaded
controlPlaneState = rotateLocalAuthorityEpoch(root, null, desiredIdentity, ...);
// after
if (!controlPlaneState) {
  controlPlaneState = await bootstrapControlPlaneState(root, desiredIdentity);
}
controlPlaneState = rotateLocalAuthorityEpoch(root, controlPlaneState, desiredIdentity, ...);
Defensive patterns

Strategy: validation

Validate before calling

const canRotateLocally = Boolean(localProvider) && controlPlaneState !== null;
if (!exactAuthority && warmRecovery === null && !canRotateLocally) {
  throw new Error("cannot rotate authority: no local state and no warm recovery");
}

Type guard

function canRotate(cpState: unknown, hasLocalProvider: boolean): boolean {
  return hasLocalProvider && cpState !== null && typeof cpState === "object";
}

Try / catch

try {
  await transport.start(params);
} catch (e) {
  if (e.message === "native_runner_prp_run_rotation_unavailable") {
    // bootstrap control-plane state, then retry
    await bootstrapControlPlaneState(root, desiredIdentity);
  }
}

Prevention

When it happens

Trigger: Authority identity differs from the current one (exactAuthority is false), warm recovery is unavailable (null), and either `localProvider` is falsy or `controlPlaneState` is null at the rotation point.

Common situations: Restarting a runner against a fresh state file so no prior control-plane state exists; disabling the local provider in configuration while relying on local rotation; corrupted or wiped runner state store losing controlPlaneState.

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


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/fbf6edd7fc7bfbb9. Report an issue: GitHub.

Appendix: source

Thrown at cli/src/commands/test-drive.ts:93

    adapterType: "opencode_local",
    credentialTarget: "OPENROUTER_API_KEY",
    credentialName: "OpenRouter API Key",
  },
};

const NON_PAPERCLIP_ISOLATED_ENV_KEYS = [
  "DATABASE_URL",
  "DATABASE_MIGRATION_URL",
  "HOST",
  "PORT",
  "SERVE_UI",
  "BETTER_AUTH_URL",
  "BETTER_AUTH_BASE_URL",
] as const;

function requiredApiResult<T>(value: T | null, action: string): T {
  if (value === null) {
    throw new Error(`Paperclip returned no result while ${action}.`);
  }
  return value;
}

function errorMessage(error: unknown): string {
  if (error instanceof Error) return error.message || error.name;
  if (typeof error === "string") return error;
  try {
    return JSON.stringify(error);
  } catch {
    return String(error);
  }
}

export function redactTestDriveText(text: string, credentials: Array<string | undefined>): string {
  let redacted = text;
  for (const credential of credentials) {
    if (!credential) continue;

View on GitHub (pinned to 01ad858492)