hcengineering/platform · error
Missing subscription data
Error message
Missing subscription data
What it means
handleSubscriptionUpdated (invoked from handlePolarWebhook for subscription.updated events) reads the subscription payload as event.data ?? event. If both are null/undefined the webhook carries no subscription object, so after logging it throws 'Missing subscription data' — the event cannot be processed at all. It protects the transformer from being handed an empty payload.
Source
Thrown at services/payment/pod-payment/src/providers/polar/webhook.ts:93
ctx.error('Failed to process Polar webhook', { err })
res.status(500).json({ error: 'Internal server error' })
}
}
/**
* Handle subscription.created/updated/active
*/
async function handleSubscriptionUpdated (
ctx: MeasureContext,
accountsUrl: string,
serviceToken: string,
event: any
): Promise<void> {
const subscription = event.data ?? event
if (subscription == null) {
ctx.error('Missing subscription data', { event })
throw new Error('Missing subscription data')
}
const subscriptionData = transformPolarSubscriptionToData(subscription)
if (subscriptionData === null) {
ctx.info('Ignoring subscription in irrelevant state', {
subscriptionId: subscription.id,
status: subscription.status
})
return
}
const accountClient = getAccountClient(accountsUrl, serviceToken)
await accountClient.upsertSubscription(subscriptionData)
ctx.info('Subscription upserted', { subscriptionId: subscription.id, status: subscriptionData.status })
}
View on GitHub (pinned to 63e28dc964)
Solutions
- Inspect the raw webhook body/logged event to confirm the payload shape and re-send a valid subscription.updated event from Polar
- Fix the webhook dispatch so only subscription events with data reach handleSubscriptionUpdated
- If testing, send a payload with subscription data under event.data (or as event itself)
- Return 4xx for such deliveries so Polar's retry/DLQ semantics kick in instead of crashing the handler
Example fix
// before
const event = JSON.parse('{}')
await handlePolarWebhook(ctx, event)
// after
const event = JSON.parse(body)
if (event?.data?.object == null && event?.id == null) {
return res.status(400).send('missing subscription data')
}
await handlePolarWebhook(ctx, event) Defensive patterns
Strategy: validation
Validate before calling
if (event?.data == null && event == null) {
return res.status(400).send('Webhook payload has no subscription data')
}
await handlePolarWebhook(ctx, serviceToken, event) Type guard
function hasSubscriptionData(event: any): boolean {
const subscription = event?.data ?? event
return subscription != null && typeof subscription === 'object' && 'id' in subscription
} Try / catch
try {
await handlePolarWebhook(ctx, serviceToken, event)
} catch (e) {
if (e.message === 'Missing subscription data') {
// ack with 400 so Polar retries/reports the delivery instead of crashing worker
} else throw e
} Prevention
- Validate and verify webhook signatures before dispatching
- Filter events by type before routing to handleSubscriptionUpdated
- Log raw bodies (redacted) for all webhook deliveries to debug malformed payloads
- Test webhook handling with Polar's example payloads and empty-payload edge cases
When it happens
Trigger: A Polar webhook delivery whose body lacks event.data and event itself is null — e.g. misrouted/malformed webhook payload, non-subscription event reaching this handler, a manually replayed/test event with an empty body, or signature-verified but truncated payload.
Common situations: Webhook endpoint receiving events from a Polar API version with a different envelope; manual testing with curl sending {} ; replaying events from a queue where the payload was stripped; a Polar outage producing empty event bodies.
Related errors
- Missing productIds for plan: ${planKey}
- Failed to cancel subscription ${providerSubscriptionId}
- Failed to uncancel subscription ${providerSubscriptionId}
- No products configured for plan: ${planKey}
- Payment service URL not specified
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/45fcdbded7604175.
Report an issue: GitHub.