{"record":{"id":"734cf3bb726f1649","repo":"vercel/ai","slug":"acp-cold-session-state-is-incompatible-with-the-cu","errorCode":null,"errorMessage":"ACP cold-session state is incompatible with the current non-secret session configuration.","messagePattern":"ACP cold-session state is incompatible with the current non-secret session configuration\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/harness-acp/src/v1/acp-v1-harness.ts","lineNumber":1837,"sourceCode":"    tools: coldSession.tools,\n    builtinTools,\n    permissionMode,\n    permissionModeMapping,\n    mcpServers,\n    debug,\n    authenticationProfile,\n    sessionMeta,\n    instructionMapping,\n    responseFormat: coldSession.responseFormat,\n    outputSchemaMapping,\n    model: undefined,\n    modelMapping,\n  });\n  if (\n    current.configurationFingerprint !== coldSession.configurationFingerprint ||\n    coldSession.permissionMode !== permissionMode\n  ) {\n    throw new Error(\n      'ACP cold-session state is incompatible with the current non-secret session configuration.',\n    );\n  }\n  return current;\n}\n\nfunction assertRecoveryToolCatalog({\n  persisted,\n  current,\n}: {\n  persisted: ReadonlyArray<HarnessV1ToolSpec>;\n  current: ReadonlyArray<HarnessV1ToolSpec>;\n}): void {\n  if (\n    fingerprintValue({ value: persisted }) !==\n    fingerprintValue({ value: current })\n  ) {\n    throw new Error(","sourceCodeStart":1819,"sourceCodeEnd":1855,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness-acp/src/v1/acp-v1-harness.ts#L1819-L1855","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Resume with the exact permissionMode stored in the cold-session state (read it from lifecycle data rather than hardcoding).","Restore the same runtime configuration that was active when the cold-session state was written.","If the configuration intentionally changed, start a new session rather than resuming the cold state.","Validate the fingerprint/permissionMode match before calling resume and surface a clear config-drift error to the user."],"exampleFix":"// before\nawait resumeACPV1({ lifecycleData, permissionMode: 'auto' }); // persisted 'default' -> throws\n// after\nawait resumeACPV1({\n  lifecycleData,\n  permissionMode: lifecycleData.coldSession.permissionMode,\n});","handlingStrategy":"validation","validationCode":"function coldSessionCompatible(cold, current) {\n  return cold?.configurationFingerprint === computeColdFingerprint(current) &&\n    cold?.permissionMode === current.permissionMode;\n}\nif (!coldSessionCompatible(lifecycleData?.coldSession, currentConfig)) { /* create new session */ }","typeGuard":null,"tryCatchPattern":"try {\n  session = await resumeACPV1({ lifecycleData });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('cold-session state is incompatible')) {\n    session = await createACPV1({ /* fresh config or persisted permissionMode */ });\n  } else throw e;\n}","preventionTips":["Always resume with the permissionMode read from the persisted cold-session state","Freeze non-secret configuration (tools, mappings, sessionMeta) for the lifetime of a session","Diff current runtime config against coldSession state before attempting cold resume"],"tags":["acp","cold-session","fingerprint","configuration-drift","permission-mode"],"backgroundTag":"configuration-fingerprint-mismatch","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}