{"record":{"id":"37b72f5ff2801efa","repo":"hcengineering/platform","slug":"failed-to-uncancel-subscription-providersubscrip","errorCode":null,"errorMessage":"Failed to uncancel subscription ${providerSubscriptionId}","messagePattern":"Failed to uncancel subscription (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/payment/pod-payment/src/providers/polar/provider.ts","lineNumber":272,"sourceCode":"    }\n  }\n\n  async cancelSubscription (ctx: MeasureContext, providerSubscriptionId: string): Promise<SubscriptionData> {\n    const polarSubscription = await this.polar.cancelSubscription(ctx, providerSubscriptionId)\n    const subscriptionData = transformPolarSubscriptionToData(polarSubscription)\n\n    if (subscriptionData == null) {\n      throw new Error(`Failed to cancel subscription ${providerSubscriptionId}`)\n    }\n\n    return subscriptionData\n  }\n\n  async uncancelSubscription (ctx: MeasureContext, providerSubscriptionId: string): Promise<SubscriptionData> {\n    const polarSubscription = await this.polar.uncancelSubscription(ctx, providerSubscriptionId)\n    const subscriptionData = transformPolarSubscriptionToData(polarSubscription)\n    if (subscriptionData == null) {\n      throw new Error(`Failed to uncancel subscription ${providerSubscriptionId}`)\n    }\n\n    return subscriptionData\n  }\n\n  async updateSubscriptionPlan (\n    ctx: MeasureContext,\n    subscriptionId: string,\n    newPlan: string,\n    workspaceUrl: string,\n    accountUuid: string\n  ): Promise<SubscriptionData | CheckoutResponse | null> {\n    // Get the current subscription to check if it's free\n    const currentSub = await this.polar.getSubscription(ctx, subscriptionId)\n\n    // Check if subscription is free by checking if it has a price with amountType === 'free'\n    const isFreeSubscription = currentSub.prices?.[0]?.amountType === 'free'\n","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/payment/pod-payment/src/providers/polar/provider.ts#L254-L290","documentation":"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.","triggerScenarios":"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>.","commonSituations":"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.","solutions":["Log/inspect the raw Polar response and extend transformPolarSubscriptionToData for the unexpected status/shape","Confirm the subscription is in a resumable state (canceled, not revoked/expired) in the Polar dashboard before retrying","Align the Polar SDK version and status enums used by the transformer","Return the raw provider data or a partial result instead of throwing when the state is recoverable"],"exampleFix":"// before\nif (subscriptionData == null) {\n  throw new Error(`Failed to uncancel subscription ${providerSubscriptionId}`)\n}\n// after (caller pre-check)\nconst sub = await getSubscription(ctx, providerSubscriptionId)\nif (sub.status !== 'canceled') throw new Error(`Subscription ${providerSubscriptionId} is not in a resumable state (status: ${sub.status})`)\nawait provider.uncancelSubscription(ctx, providerSubscriptionId)","handlingStrategy":"type-guard","validationCode":"const sub = await provider.getSubscription(ctx, providerSubscriptionId)\nif (sub.status !== 'canceled') throw new Error(`Cannot uncancel: status is ${sub.status}`)","typeGuard":"function isTransformableSubscription(x: unknown): boolean {\n  return typeof x === 'object' && x !== null && 'id' in x && 'status' in x && Array.isArray((x as any).prices)\n}","tryCatchPattern":"try {\n  await provider.uncancelSubscription(ctx, providerSubscriptionId)\n} catch (e) {\n  if (e.message.startsWith('Failed to uncancel subscription')) {\n    // inspect Polar dashboard/refresh state; do not blind-retry\n  } else throw e\n}","preventionTips":["Only uncancel subscriptions in a resumable (canceled) state","Keep transformer status-enum coverage aligned with Polar SDK","Test uncancel against sandbox subscriptions with all statuses","Log raw responses when the transform returns null"],"tags":["payment","polar","transformation","api-response"],"backgroundTag":"subscription-transform-failed","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}