{"record":{"id":"a8b1635654fa89b4","repo":"koala73/worldmonitor","slug":"activation-outcome-revision-must-be-an-integer-fro","errorCode":null,"errorMessage":"activation outcome revision must be an integer from 1 to ${MAX_PRO_ACTIVATION_OUTCOME_REVISION}","messagePattern":"activation outcome revision must be an integer from 1 to (.+?)","errorType":"validation","errorClass":"ConvexError","httpStatus":null,"severity":"error","filePath":"convex/payments/billing.ts","lineNumber":983,"sourceCode":"      ctx,\n      args.activationKey,\n      args.cohort,\n    );\n    if (\n      presentation === null ||\n      presentation.userId !== userId ||\n      presentation.claimNonce !== args.claimNonce ||\n      presentation.exitedAt !== undefined\n    ) {\n      return false;\n    }\n\n    if (\n      !Number.isSafeInteger(args.revision) ||\n      args.revision < 1 ||\n      args.revision > MAX_PRO_ACTIVATION_OUTCOME_REVISION\n    ) {\n      throw new ConvexError(\n        `activation outcome revision must be an integer from 1 to ${MAX_PRO_ACTIVATION_OUTCOME_REVISION}`,\n      );\n    }\n    const allSteps = [\n      ...args.confirmedSteps,\n      ...args.skippedSteps,\n      ...(args.blockedSteps ?? []),\n      ...args.failedSteps,\n    ];\n    if (\n      allSteps.length > proActivationStepIdValidator.members.length ||\n      new Set(allSteps).size !== allSteps.length\n    ) {\n      throw new ConvexError(\n        `activation outcome buckets must be disjoint and contain at most ${proActivationStepIdValidator.members.length} steps`,\n      );\n    }\n    if (args.revision <= (presentation.outcomeRevision ?? 0)) {","sourceCodeStart":965,"sourceCodeEnd":1001,"githubUrl":"https://github.com/koala73/worldmonitor/blob/9361220cc013571781071f0206e4d80fd14b2f7f/convex/payments/billing.ts#L965-L1001","documentation":"ConvexError guard in the Pro activation outcome recorder validating the revision argument: it must be a safe integer between 1 and MAX_PRO_ACTIVATION_OUTCOME_REVISION. Fires when the client reports an outcome with an out-of-range, zero, negative, or fractional revision number, protecting the append-only outcome revision history.","triggerScenarios":"Thrown at convex/payments/billing.ts:967 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Send revision as the next integer after the last recorded revision for the presentation","Never reset or reuse revision numbers; cap updates at MAX_PRO_ACTIVATION_OUTCOME_REVISION","Regenerate the client's revision counter from the server's current presentation state"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"9361220cc013571781071f0206e4d80fd14b2f7f","analyzedAt":"2026-08-21T16:51:25.751Z","contentChangedAt":"2026-08-21T16:51:25.751Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}