{"record":{"id":"a8b7ad08cc9c024e","repo":"paperclipai/paperclip","slug":"discord-command-registration-persistence-unproven","errorCode":null,"errorMessage":"Discord command registration persistence unproven","messagePattern":"Discord command registration persistence unproven","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/src/services/chat-discord-command-registration.ts","lineNumber":449,"sourceCode":"    ...input,\n    scope: state.scope,\n    state,\n    runtimeFence: Object.freeze(runtimeFence.data),\n    verifiedIdentity: Object.freeze({ ...input.verifiedIdentity }),\n  };\n  const authorize = async (stage: DiscordCommandRegistrationStage) => {\n    try {\n      await input.authorize(stage);\n    } catch {\n      throw new Error(\"Discord command registration authorization denied\");\n    }\n  };\n  const persist = async (next: DiscordCommandRegistration) => {\n    freezeState(next);\n    try {\n      await input.commit(state!, next);\n    } catch {\n      throw new Error(\"Discord command registration persistence unproven\");\n    }\n    state = next;\n  };\n  const settle = async (\n    command: RemoteCommand,\n  ): Promise<DiscordCommandRegistrationResult> => {\n    const next: Extract<DiscordCommandRegistration, { phase: \"registered\" }> = {\n      schema: state!.schema,\n      scope: state!.scope,\n      ownerId: state!.ownerId,\n      phase: \"registered\",\n      receipt: {\n        commandId: command.id,\n        version: command.version,\n        definitionDigest: definitionDigest(state!.ownerId),\n      },\n    };\n    freezeState(next);","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/chat-discord-command-registration.ts#L431-L467","documentation":"The internal persist() step calls the caller-supplied commit(state, next) hook to durably store the new registration state; any throw is converted to 'Discord command registration persistence unproven'. Because the next in-memory state is only adopted after commit succeeds, a failure means the new phase could not be proven durable and reconciliation aborts.","triggerScenarios":"The commit callback throws — database unavailable, unique-constraint conflict, transaction deadlock, serialization failure, or the hook rejecting the frozen next state blob.","commonSituations":"Postgres connection pool exhaustion or failover during reconciliation; a migration/unique index conflict on the state row; the storage layer enforcing a schema the new state doesn't match; network blip between server and DB.","solutions":["Check the commit hook's own storage layer for the underlying error (it is swallowed here).","Retry reconciliation once the database is healthy; state is unchanged on failure so it is safe.","Fix constraint/schema mismatches between the state blob and the persistence table.","Make the commit hook idempotent and retryable for transient DB errors."],"exampleFix":"// before (app's commit hook)\nawait db.insert(registrations).values(next); // throws on conflict\n// after\nawait db.insert(registrations)\n  .values(next)\n  .onConflictDoUpdate({ target: registrations.key, set: next });","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await reconcileDiscordCommandRegistration(input); }\ncatch (e) {\n  if ((e as Error).message === \"Discord command registration persistence unproven\") {\n    await sleep(backoff()); return retry(); // in-memory state unchanged; safe to retry\n  }\n  throw e;\n}","preventionTips":["Make commit hooks idempotent and conflict-tolerant (upsert semantics).","Monitor DB health/pool saturation; persist failures are usually infra-level.","Keep the persisted state schema in sync with what freeze/commit expects."],"tags":["persistence","database","discord"],"backgroundTag":"database-write-failed","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}