vercel/ai · error · Error

ACP cold-session state is incompatible with the current non-

Error message

ACP cold-session state is incompatible with the current non-secret session configuration.

What it means

validateACPColdSessionConfiguration recomputes a configuration fingerprint from the persisted cold-session state using the CURRENT non-secret runtime configuration and also compares the persisted permissionMode. A fingerprint mismatch or a different permissionMode means the cold-session state cannot be faithfully restored under the current configuration, so the harness throws instead of resuming with altered semantics.

Source

Thrown at packages/harness-acp/src/v1/acp-v1-harness.ts:1837

    tools: coldSession.tools,
    builtinTools,
    permissionMode,
    permissionModeMapping,
    mcpServers,
    debug,
    authenticationProfile,
    sessionMeta,
    instructionMapping,
    responseFormat: coldSession.responseFormat,
    outputSchemaMapping,
    model: undefined,
    modelMapping,
  });
  if (
    current.configurationFingerprint !== coldSession.configurationFingerprint ||
    coldSession.permissionMode !== permissionMode
  ) {
    throw new Error(
      'ACP cold-session state is incompatible with the current non-secret session configuration.',
    );
  }
  return current;
}

function assertRecoveryToolCatalog({
  persisted,
  current,
}: {
  persisted: ReadonlyArray<HarnessV1ToolSpec>;
  current: ReadonlyArray<HarnessV1ToolSpec>;
}): void {
  if (
    fingerprintValue({ value: persisted }) !==
    fingerprintValue({ value: current })
  ) {
    throw new Error(

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Resume with the exact permissionMode stored in the cold-session state (read it from lifecycle data rather than hardcoding).
  2. Restore the same runtime configuration that was active when the cold-session state was written.
  3. If the configuration intentionally changed, start a new session rather than resuming the cold state.
  4. Validate the fingerprint/permissionMode match before calling resume and surface a clear config-drift error to the user.

Example fix

// before
await resumeACPV1({ lifecycleData, permissionMode: 'auto' }); // persisted 'default' -> throws
// after
await resumeACPV1({
  lifecycleData,
  permissionMode: lifecycleData.coldSession.permissionMode,
});
Defensive patterns

Strategy: validation

Validate before calling

function coldSessionCompatible(cold, current) {
  return cold?.configurationFingerprint === computeColdFingerprint(current) &&
    cold?.permissionMode === current.permissionMode;
}
if (!coldSessionCompatible(lifecycleData?.coldSession, currentConfig)) { /* create new session */ }

Try / catch

try {
  session = await resumeACPV1({ lifecycleData });
} catch (e) {
  if (e instanceof Error && e.message.includes('cold-session state is incompatible')) {
    session = await createACPV1({ /* fresh config or persisted permissionMode */ });
  } else throw e;
}

Prevention

When it happens

Trigger: Resuming a cold session (from coldSession state in lifecycle data) when the current permissionMode differs from the persisted one, or when any non-secret configuration input (builtinTools, permissionModeMapping, modelMapping, outputSchemaMapping, instructionMapping, authenticationProfile, sessionMeta, mcpServers, debug) changed since the state was persisted.

Common situations: Changing permission mode (e.g. from 'default' to 'yolo'/auto-approve) between persisting and resuming; harness upgrade altering builtin tool catalogs or mappings; resuming on a differently configured host or with different auth identity; edited sessionMeta.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/734cf3bb726f1649. Report an issue: GitHub.