paperclipai/paperclip · error · Error
native_execution_input_persisted_binding_mismatch
native_execution_input_persisted_binding_mismatch
Error message
native_execution_input_persisted_binding_mismatch
What it means
prepareNativeSessionBootstrapPersistence compares the run's persisted runnerProfileJson.nativeExecutionInput against the execution input currently being persisted. Once a run has recorded its native execution input (prompt model, cwd, settings, etc.), that binding is immutable. This error means the caller is trying to bind a different native execution configuration to a run that already has one.
Solutions
- Ensure input.execution matches the persisted profile exactly; reuse the run's existing nativeExecutionInput when re-invoking.
- Start a new run when the execution input (prompt, cwd, model) differs instead of rebinding the existing run.
- Normalize/validate the execution object before comparison so key ordering and optional fields serialize identically.
- Inspect the run's runnerProfileJson to see the stored binding and reconcile the caller with it.
Example fix
// before
prepareNativeSessionBootstrapPersistence(db, { run, selectedSessionId, execution: { prompt, cwd, settings: newSettings }, restoringCheckpoint: false });
// after
const execution = parseNativeExecutionInput(record(run.runnerProfileJson).nativeExecutionInput) ?? { prompt, cwd, settings: newSettings };
prepareNativeSessionBootstrapPersistence(db, { run, selectedSessionId, execution, restoringCheckpoint: false }); Defensive patterns
Strategy: validation
Validate before calling
function matchesPersistedExecution(run, execution) {
const profile = record(run.runnerProfileJson);
if (profile.nativeExecutionInput === undefined) return true;
return isDeepStrictEqual(parseNativeExecutionInput(profile.nativeExecutionInput), execution);
} Type guard
const isCompatibleRun = (run, execution) => record(run.runnerProfileJson).nativeExecutionInput === undefined || isDeepStrictEqual(parseNativeExecutionInput(record(run.runnerProfileJson).nativeExecutionInput), execution);
Try / catch
try {
await prepareNativeSessionBootstrapPersistence(db, { run, selectedSessionId, execution, restoringCheckpoint });
} catch (e) {
if (e.message === "native_execution_input_persisted_binding_mismatch") {
// rebind onto a fresh run with the new execution input
return createRunWithExecution(execution);
}
throw e;
} Prevention
- Reuse the persisted nativeExecutionInput whenever re-invoking bootstrap on the same run.
- Serialize NativeExecutionInput deterministically (fixed key order, normalized optionals) before persistence and comparison.
- Create a new run whenever prompt/model/cwd/settings change.
- Add a pre-check comparing the intended execution against runnerProfileJson before calling the API.
When it happens
Trigger: prepareNativeSessionBootstrapPersistence is called and profile.nativeExecutionInput !== undefined while isDeepStrictEqual(parseNativeExecutionInput(profile.nativeExecutionInput), input.execution) is false — i.e., the run row already stores a nativeExecutionInput that deep-inequality-compares with the supplied execution object.
Common situations: Re-running bootstrap with changed prompt/model/cwd/settings for the same run; resuming a run with execution input serialized in a different key order or with extra fields; passing a different run row that was bootstrapped for a different execution; a code change altering the NativeExecutionInput shape so deep-equality breaks against old persisted profiles.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Discord Application ID does not match the supplied bot token
- ${error}
- GitHub did not confirm the expected secure Paperclip…
- Immutable campaign already exists with a different digest
- Immutable campaign history changed for
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/367786b02cc80154.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/native-runtime/native-session-resume.ts:286
nativeSessionId: string | null;
};
selectedSessionId: string;
execution: NativeExecutionInput;
restoringCheckpoint: boolean;
},
) {
const hasProviderEvents = (
await nativeSessionProviderEvidence(db, [input.run.id])
).has(input.run.id);
const profile = record(input.run.runnerProfileJson);
if (
profile.nativeExecutionInput !== undefined &&
!isDeepStrictEqual(
parseNativeExecutionInput(profile.nativeExecutionInput),
input.execution,
)
) {
throw new Error("native_execution_input_persisted_binding_mismatch");
}
if (
input.restoringCheckpoint &&
!isUnusedNativeSessionBootstrap(input.run, hasProviderEvents)
) {
throw new Error("native_session_bootstrap_identity_conflict");
}
return nativeSessionIdForBootstrapPersistence({
...input,
hasProviderEvents,
});
}
/**
* Legacy compatibility is deliberately narrower than ordinary task-session
* continuation: only a replacement row that never acquired any native process
* or provider authority may be rebound to a terminal native source. The exact
* checkpoint/session/workspace/provider binding is validated separately byView on GitHub (pinned to 3f1d897a7c)