paperclipai/paperclip · error

initialize the ACPX sidecar first

Error message

initialize the ACPX sidecar first

What it means

The ACPX runtime sidecar's dispatch() requires that the sidecar has been initialized with an agent/model profile before processing open requests. If initializedModel is not set, dispatch throws "initialize the ACPX sidecar first" because there is no profile against which session opens can be validated and no host configuration to open with.

Source

Thrown at packages/paperclip-runner/src/cli/acpx-runtime-sidecar.ts:247

        persistentSessions: true,
        exactModelVerification: true,
        permissions: "runner_policy",
        semanticTools: "runner_bridge",
        structuredInput: "paperclip.question_set.v1",
      },
    };
  }
  if (request.command === "session.open") {
    if (
      hasSidecarSessionOwnership(
        host,
        activeHostCleanup,
        failedAdmissionCleanup,
      )
    ) {
      throw new Error("ACPX sidecar already owns a session or its cleanup");
    }
    if (!initializedModel) throw new Error("initialize the ACPX sidecar first");
    const params = parseOpenParams(request.params);
    if (
      params.agent !== initializedAgent ||
      params.model !== initializedModel
    ) {
      throw new Error("ACPX session profile differs from its initialization");
    }
    const openedHost = await AcpxRuntimeHost.open(
      {
        runtimeDirectory: params.runtimeDirectory,
        normalizedSessionId: params.normalizedSessionId,
        workingDirectory: params.workingDirectory,
        agent: params.agent,
        model: params.model,
        permissionMode: params.permissionMode,
        systemInstructions: params.systemInstructions,
        environment: process.env,
        expectedIdentity: params.expectedIdentity,

View on GitHub (pinned to 01ad858492)

Solutions

  1. Send the initialize request (with agent/model) before any open/session requests
  2. Re-initialize the sidecar after restart or reconnect before resuming dispatch
  3. Add a client-side readiness gate that blocks requests until init is acknowledged
  4. Inspect sidecar startup logs to confirm initialization completed

Example fix

// before
sidecar.dispatch({ method: 'session/open', params });
// after
if (!sidecar.isInitialized()) {
  await sidecar.dispatch({ method: 'initialize', params: { agent, model } });
}
sidecar.dispatch({ method: 'session/open', params });
Defensive patterns

Strategy: validation

Validate before calling

if (!sidecar.isInitialized()) await sidecar.initialize({ agent, model });

Type guard

const sidecarReady = (s: { initializedModel?: string | null }): s is { initializedModel: string } => typeof s.initializedModel === 'string' && s.initializedModel.length > 0;

Try / catch

try { sidecar.dispatch(request); } catch (e) { if (e.message === 'initialize the ACPX sidecar first') { await sidecar.initialize(initParams); return sidecar.dispatch(request); } throw e; }

Prevention

When it happens

Trigger: Sending an open (or other session) JSON-RPC request to the sidecar before the initialize request; a lost/restarted sidecar process whose initialization state was wiped while the client kept its old connection; racing the open request ahead of initialization.

Common situations: Client bug skipping the initialize handshake; sidecar crash-recovery reusing a stale client; tests or scripts invoking dispatch directly without setup; transport reconnect that spawned a fresh sidecar.

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/91373a9f4514eba9. Report an issue: GitHub.