hcengineering/platform · critical

Failed to uncancel subscription at provider

Error message

Failed to uncancel subscription at provider

What it means

This 500 is returned when provider.uncancelSubscription(...) throws while asking the external payment provider to re-activate a canceled subscription. The raw error is logged via ctx.error and a generic message is returned to the client. Common underlying causes are provider API errors, invalid credentials, or the provider refusing reactivation of that subscription.

Source

Thrown at services/payment/pod-payment/src/server.ts:349

        async (ctx) => {
          const subscriptionId = req.params.subscriptionId

          // Get subscription from our database using internal ID
          const subscription = await accountClient.getSubscriptionById(subscriptionId)

          if (subscription === undefined || subscription === null) {
            res.status(404).json({ error: 'Subscription not found' })
            return
          }

          let uncanceledSubscription: SubscriptionData | null

          try {
            // Uncancel via provider using the provider's subscription ID
            uncanceledSubscription = await provider.uncancelSubscription(ctx, subscription.providerSubscriptionId)
          } catch (err) {
            ctx.error('Failed to uncancel subscription at provider', { err })
            res.status(500).json({ error: 'Failed to uncancel subscription at provider' })
            return
          }

          if (uncanceledSubscription === null) {
            res.status(404).json({ error: 'Failed to uncancel subscription at provider' })
            return
          }

          // Upsert the updated subscription into our database
          await accountClient.upsertSubscription(uncanceledSubscription)

          res.status(200).json(uncanceledSubscription)
        },
        req,
        res,
        () => {}
      )
    }

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Read the server logs (ctx.error 'Failed to uncancel subscription at provider') for the provider's concrete error.
  2. Check the provider dashboard: if the subscription is fully terminated, create a new subscription instead of un-canceling.
  3. Verify provider credentials match the account that owns providerSubscriptionId.
  4. Retry with backoff for transient provider/network errors.
  5. If the provider says the subscription cannot be revived, re-subscribe the workspace and update the local record.

Example fix

// before
await provider.uncancelSubscription(ctx, sub.providerSubscriptionId) // throws: cancellation already finalized

// after
try {
  await provider.uncancelSubscription(ctx, sub.providerSubscriptionId)
} catch (reviveErr) {
  // fall back to a fresh checkout
  await provider.createSubscription(ctx, request, workspaceUuid, workspaceUrl, accountUuid)
}
Defensive patterns

Strategy: fallback

Validate before calling

const remote = await provider.getSubscription(ctx, sub.providerSubscriptionId)
if (remote !== null && remote.status === 'active') {
  // already active; skip uncancel entirely
}
if (remote === null) {
  // cannot revive; plan a fresh createSubscription flow instead
}

Type guard

function isRevivable(s: SubscriptionData | null): boolean {
  return s !== null && (s.status === 'canceled' || s.status === 'canceling')
}

Try / catch

try {
  await uncancelSubscription(id)
} catch (e) {
  // fall back: create a new subscription via checkout instead of failing the user
  await startFreshCheckout(workspaceUuid)
}

Prevention

When it happens

Trigger: POST /api/v1/subscriptions/:subscriptionId/uncancel where the local record exists but provider.uncancelSubscription throws — provider-side subscription already fully terminated (cannot be revived), unknown providerSubscriptionId, expired/invalid provider API keys, provider outage, or network timeout.

Common situations: Trying to uncancel after the provider has completed the cancellation at period end (no longer revivable); provider account/key mismatch; provider incident; subscription migrated between provider accounts so the stored ID no longer resolves.

Related errors


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