koala73/worldmonitor · error · ConvexError

activation session start must be a positive safe integer wit

Error message

activation session start must be a positive safe integer within the allowed future clock skew

What it means

ConvexError guard in the Pro activation presentation flow validating the optional sessionStartedAt argument: it must be a positive safe integer not further in the future than MAX_PRO_ACTIVATION_SESSION_FUTURE_SKEW_MS past server time. Fires when the client sends a non-integer, zero/negative, or excessively future-skewed timestamp, rejecting clock-tampered or malformed session claims.

Source

Thrown at convex/payments/billing.ts:846

    // re-create the blind spot this record exists to close.
    if (
      subscription === null ||
      subscription.userId !== userId ||
      !isProActivationPlan(subscription.planKey)
    ) {
      return { status: "not_eligible" as const };
    }

    const now = Date.now();
    if (
      args.sessionStartedAt !== undefined &&
      (
        !Number.isSafeInteger(args.sessionStartedAt) ||
        args.sessionStartedAt <= 0 ||
        args.sessionStartedAt > now + MAX_PRO_ACTIVATION_SESSION_FUTURE_SKEW_MS
      )
    ) {
      throw new ConvexError(
        "activation session start must be a positive safe integer within the allowed future clock skew",
      );
    }

    const existing = await activationPresentationForCohort(ctx, args.activationKey, "day0");
    if (existing === null) {
      await ctx.db.insert("proActivationPresentations", {
        userId,
        subscriptionId: args.activationKey,
        cohort: "day0",
        claimNonce: args.claimNonce,
        claimedAt: now,
        ...(args.sessionStartedAt !== undefined
          ? { sessionStartedAt: args.sessionStartedAt }
          : {}),
        // Day-0 has no confirm handshake, so presentation is recorded here —
        // before the interstitial renders — to keep a subscriber who closes
        // the tab immediately inside the cohort instead of invisible.

View on GitHub (pinned to 9361220cc0)

Solutions

  1. Send sessionStartedAt as an integer millisecond epoch from Date.now() on the client
  2. Ensure the client clock is reasonably synced; large future skew is rejected by design
  3. Omit the field if no custom session start timestamp is needed
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at convex/payments/billing.ts:830 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-08-21). Data as JSON: /api/errors/57c1728c180bd3c8. Report an issue: GitHub.