hcengineering/platform · error

Failed to uncancel subscription ${providerSubscriptionId}

Error message

Failed to uncancel subscription ${providerSubscriptionId}

What it means

uncancelSubscription resumes a previously canceled subscription via the Polar API and pipes the result through transformPolarSubscriptionToData. A null transform result means the returned subscription is not in a recognizable state, so the provider throws 'Failed to uncancel subscription <id>'. Like error 806, the remote call may have succeeded while the response mapping failed.

Source

Thrown at services/payment/pod-payment/src/providers/polar/provider.ts:272

    }
  }

  async cancelSubscription (ctx: MeasureContext, providerSubscriptionId: string): Promise<SubscriptionData> {
    const polarSubscription = await this.polar.cancelSubscription(ctx, providerSubscriptionId)
    const subscriptionData = transformPolarSubscriptionToData(polarSubscription)

    if (subscriptionData == null) {
      throw new Error(`Failed to cancel subscription ${providerSubscriptionId}`)
    }

    return subscriptionData
  }

  async uncancelSubscription (ctx: MeasureContext, providerSubscriptionId: string): Promise<SubscriptionData> {
    const polarSubscription = await this.polar.uncancelSubscription(ctx, providerSubscriptionId)
    const subscriptionData = transformPolarSubscriptionToData(polarSubscription)
    if (subscriptionData == null) {
      throw new Error(`Failed to uncancel subscription ${providerSubscriptionId}`)
    }

    return subscriptionData
  }

  async updateSubscriptionPlan (
    ctx: MeasureContext,
    subscriptionId: string,
    newPlan: string,
    workspaceUrl: string,
    accountUuid: string
  ): Promise<SubscriptionData | CheckoutResponse | null> {
    // Get the current subscription to check if it's free
    const currentSub = await this.polar.getSubscription(ctx, subscriptionId)

    // Check if subscription is free by checking if it has a price with amountType === 'free'
    const isFreeSubscription = currentSub.prices?.[0]?.amountType === 'free'

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Log/inspect the raw Polar response and extend transformPolarSubscriptionToData for the unexpected status/shape
  2. Confirm the subscription is in a resumable state (canceled, not revoked/expired) in the Polar dashboard before retrying
  3. Align the Polar SDK version and status enums used by the transformer
  4. Return the raw provider data or a partial result instead of throwing when the state is recoverable

Example fix

// before
if (subscriptionData == null) {
  throw new Error(`Failed to uncancel subscription ${providerSubscriptionId}`)
}
// after (caller pre-check)
const sub = await getSubscription(ctx, providerSubscriptionId)
if (sub.status !== 'canceled') throw new Error(`Subscription ${providerSubscriptionId} is not in a resumable state (status: ${sub.status})`)
await provider.uncancelSubscription(ctx, providerSubscriptionId)
Defensive patterns

Strategy: type-guard

Validate before calling

const sub = await provider.getSubscription(ctx, providerSubscriptionId)
if (sub.status !== 'canceled') throw new Error(`Cannot uncancel: status is ${sub.status}`)

Type guard

function isTransformableSubscription(x: unknown): boolean {
  return typeof x === 'object' && x !== null && 'id' in x && 'status' in x && Array.isArray((x as any).prices)
}

Try / catch

try {
  await provider.uncancelSubscription(ctx, providerSubscriptionId)
} catch (e) {
  if (e.message.startsWith('Failed to uncancel subscription')) {
    // inspect Polar dashboard/refresh state; do not blind-retry
  } else throw e
}

Prevention

When it happens

Trigger: polar.uncancelSubscription returns a subscription the transformer cannot map — unknown status after resume, missing prices/product fields, or a response from an already-active subscription whose shape differs — for id <id>.

Common situations: Uncanceling a subscription that was fully revoked (not merely canceled) so Polar cannot resume it; Polar SDK/API schema drift; transformer missing a newly introduced status enum; production data (custom products) not covered by transformer tests.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/37b72f5ff2801efa. Report an issue: GitHub.