{"record":{"id":"acdaf62a81eed6fd","repo":"paperclipai/paperclip","slug":"native-session-bootstrap-identity-conflict","errorCode":"native_session_bootstrap_identity_conflict","errorMessage":"native_session_bootstrap_identity_conflict","messagePattern":"native_session_bootstrap_identity_conflict","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/src/services/native-runtime/native-session-resume.ts","lineNumber":257,"sourceCode":"      db,\n      runs.map((run) => run.id),\n    ),\n  });\n}\n\n/** A preassigned session id may rotate only before immutable native admission. */\nexport function nativeSessionIdForBootstrapPersistence(input: {\n  run: NativeSessionBootstrapState & { nativeSessionId: string | null };\n  selectedSessionId: string;\n  hasProviderEvents: boolean;\n}): string {\n  if (input.run.nativeSessionId === input.selectedSessionId)\n    return input.selectedSessionId;\n  if (\n    record(input.run.runnerProfileJson).nativeExecutionInput !== undefined ||\n    !isUnusedNativeSessionBootstrap(input.run, input.hasProviderEvents)\n  ) {\n    throw new Error(\"native_session_bootstrap_identity_conflict\");\n  }\n  return input.selectedSessionId;\n}\n\n/** Caller holds the run row lock; recheck authority after waiting for that lock. */\nexport async function prepareNativeSessionBootstrapPersistence(\n  db: Pick<Db, \"select\">,\n  input: {\n    run: NativeSessionBootstrapState & {\n      id: string;\n      nativeSessionId: string | null;\n    };\n    selectedSessionId: string;\n    execution: NativeExecutionInput;\n    restoringCheckpoint: boolean;\n  },\n) {\n  const hasProviderEvents = (","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/native-runtime/native-session-resume.ts#L239-L275","documentation":"nativeSessionIdForBootstrapPersistence guards the identity of a native (harness-managed) session id when persisting bootstrap state for a run. A run's nativeSessionId is immutable once the native execution has actually started (the runner profile records nativeExecutionInput or provider events exist); it may only rotate while the bootstrap is provably unused. This error means the code tried to assign a different session id to a run whose native identity is already committed.","triggerScenarios":"Called via prepareNativeSessionBootstrapPersistence when input.run.nativeSessionId !== input.selectedSessionId AND either (a) record(run.runnerProfileJson).nativeExecutionInput is defined (execution input already persisted), or (b) isUnusedNativeSessionBootstrap(run, hasProviderEvents) returns false (run already emitted provider/session events or is otherwise no longer an unused bootstrap).","commonSituations":"Re-running bootstrap with a fresh harness-generated session id against a run that already started; a concurrent resume run winning the race for the same native session; retrying bootstrap after a crash that already emitted provider events; passing the wrong run row into the persistence step.","solutions":["Reuse the run's existing nativeSessionId instead of the newly selected one — only rotate before first use.","Check heartbeat_run_events for the run (provider.event, session.*) to confirm whether the session was already used before choosing to rotate.","Create a fresh run for the new session id rather than re-binding an existing run.","Inspect run.runnerProfileJson.nativeExecutionInput: if present, the binding is immutable and selectedSessionId must equal the persisted value."],"exampleFix":"// before\nawait prepareNativeSessionBootstrapPersistence(db, { run, selectedSessionId: newSessionId, ... });\n// after\nconst selectedSessionId = run.nativeSessionId ?? newSessionId;\nawait prepareNativeSessionBootstrapPersistence(db, { run, selectedSessionId, ... });","handlingStrategy":"type-guard","validationCode":"function canRotateSessionId(run: { nativeSessionId: string | null; runnerProfileJson: unknown }, hasProviderEvents: boolean, selectedSessionId: string) {\n  if (run.nativeSessionId === selectedSessionId) return true;\n  const profile = record(run.runnerProfileJson);\n  return profile.nativeExecutionInput === undefined && isUnusedNativeSessionBootstrap(run, hasProviderEvents);\n}","typeGuard":"const canRotate = (run, selectedSessionId, hasProviderEvents) => run.nativeSessionId === selectedSessionId || (record(run.runnerProfileJson).nativeExecutionInput === undefined && isUnusedNativeSessionBootstrap(run, hasProviderEvents));","tryCatchPattern":"try {\n  const sessionId = await prepareNativeSessionBootstrapPersistence(db, input);\n} catch (e) {\n  if (e.message === \"native_session_bootstrap_identity_conflict\") {\n    // fall back to the run's existing native session id\n    return input.run.nativeSessionId;\n  }\n  throw e;\n}","preventionTips":["Always prefer the run's existing nativeSessionId over a newly selected one.","Query heartbeat_run_events for provider evidence before deciding to rotate a session id.","Never reuse a run row across distinct native sessions; create a new run instead.","Log runnerProfileJson.nativeExecutionInput presence when debugging bootstrap failures."],"tags":["native-runtime","session-resume","state-conflict","race-condition"],"backgroundTag":"invalid-state-transition","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}