paperclipai/paperclip · error

native_runner_authority_unavailable

Error message

native_runner_authority_unavailable

What it means

The warm runner connection awaiter requires a live runner core ('authority') instance. If the transport's internal #core reference is null — meaning no native runner core has been started or it was torn down — it throws this error instead of waiting for a connection that can never arrive.

Source

Thrown at packages/paperclip-runner/src/live/runnerd-codex-transport.ts:3563

        consecutiveReadyProbes += 1;
        // A second barrier prevents a provider frame emitted immediately after
        // its terminal notification from racing the authority rotation. Each
        // snapshot wakes runnerd, polls the provider, and drains the preceding
        // durable event prefix before the next probe.
        if (consecutiveReadyProbes >= 2) return;
      } else {
        consecutiveReadyProbes = 0;
      }
      await new Promise<void>((resolveWait) => setTimeout(resolveWait, 25));
    }
    throw new Error(
      `native_runner_warm_attachment_not_quiescent: ${JSON.stringify(lastBlockers)}`,
    );
  }

  async #awaitWarmRunnerConnection(deadline: number): Promise<void> {
    const core = this.#core;
    if (core === null) throw new Error("native_runner_authority_unavailable");
    let reportedReconnectWait = false;
    while (Date.now() < deadline) {
      this.#throwIfFailed();
      const connectionCount = core.activeRunnerConnectionCount();
      if (connectionCount === 1) {
        if (reportedReconnectWait) {
          this.#diagnostic(
            "warm runner re-authenticated before authority rotation",
          );
        }
        return;
      }
      if (connectionCount > 1) {
        throw new Error(
          `native_runner_warm_attachment_ambiguous: expected one authenticated runner, found ${connectionCount}`,
        );
      }
      if (!reportedReconnectWait) {

View on GitHub (pinned to 01ad858492)

Solutions

  1. Ensure the transport is fully started (startupComplete) before attempting warm attachment
  2. Check startup logs for an earlier failure that prevented core creation
  3. Re-create/restart the transport if the core was disposed
  4. Guard callers with an isStarted/core-present check before invoking rotation paths

Example fix

// before
await transport.attachRun({ runId, turnId, itemId });
// after
if (!transport.isStarted) throw new Error('start transport before attachRun');
await transport.attachRun({ runId, turnId, itemId });
Defensive patterns

Strategy: type-guard

Validate before calling

if (transport.getCore?.() == null) throw new Error('runner core not initialized');

Type guard

function hasCore(t) {
  return t != null && typeof t.getCore === 'function' && t.getCore() !== null;
}

Try / catch

try {
  await transport.attachRun(input);
} catch (e) {
  if (e.message === 'native_runner_authority_unavailable') {
    await transport.start();
    await transport.attachRun(input);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling #awaitWarmRunnerConnection (e.g. via attachRun or warm recovery) after the runner core has been disposed, or before startup created it; a failed startup leaving #core null.

Common situations: Calling attach during transport shutdown; startup crashed earlier so the core never initialized; lifecycle races where stop() ran concurrently with warm attachment.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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