hcengineering/platform · error
Subscription not found
Error message
Subscription not found
What it means
Before canceling, the endpoint looks up the subscription in the service's own database via accountClient.getSubscriptionById using the internal subscription ID from the URL path. If nothing is found (undefined or null) it returns HTTP 404. The provider is never contacted, meaning the ID does not correspond to any locally tracked subscription.
Source
Thrown at services/payment/pod-payment/src/server.ts:281
withToken,
withOwner,
(req: RequestWithAuth, res: Response) => {
if (provider === undefined) {
res.status(503).json({ error: 'Payment provider is not configured' })
return
}
void handleRequest(
ctx,
'cancel-subscription',
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 canceledSubscription: SubscriptionData | null
try {
// Cancel via provider using the provider's subscription ID
canceledSubscription = await provider.cancelSubscription(ctx, subscription.providerSubscriptionId)
} catch (err) {
ctx.error('Failed to cancel subscription at provider', { err })
res.status(500).json({ error: 'Failed to cancel subscription at provider' })
return
}
if (canceledSubscription === null) {
res.status(404).json({ error: 'Failed to cancel subscription at provider' })
return
}View on GitHub (pinned to 63e28dc964)
Solutions
- Verify the subscriptionId is the internal subscription ID (not the provider's ID) and matches an existing record.
- List the workspace's subscriptions via the account API to obtain a valid ID.
- Check you are pointing at the correct environment's account service/DB (staging vs production).
- If the record should exist, investigate the account service DB for missing/unsynced subscription rows and re-sync from the provider.
Example fix
// before (provider ID used)
POST /api/v1/subscriptions/sub_1NproviderID/cancel // -> 404
// after (internal ID)
const sub = await accountClient.listSubscriptions(workspaceUuid)[0]
POST /api/v1/subscriptions/${sub.id}/cancel // -> 200 Defensive patterns
Strategy: validation
Validate before calling
const sub = await accountClient.getSubscriptionById(subscriptionId)
if (sub === undefined || sub === null) {
throw new Error(`Subscription ${subscriptionId} not found locally; fetch a valid internal ID first`)
} Type guard
function subscriptionExists(s: SubscriptionData | undefined | null): s is SubscriptionData {
return s !== undefined && s !== null
} Try / catch
const res = await fetch(cancelUrl, opts)
if (res.status === 404 && (await res.json()).error === 'Subscription not found') {
// re-list subscriptions to get a fresh internal ID; do not blindly retry
} Prevention
- Always resolve IDs from a fresh list-subscriptions call, never from cache or the provider's ID.
- Label fields explicitly (internal id vs providerSubscriptionId) in client models.
- Pin clients to the correct environment's account service.
- Avoid deleting local subscription rows immediately after cancellation; archive instead.
When it happens
Trigger: POST /api/v1/subscriptions/:subscriptionId/cancel with a subscriptionId that is not in the local DB: typo'd ID, using the provider's subscription ID instead of the internal one, a subscription belonging to a different environment (staging vs prod DB), or a record deleted/never synced.
Common situations: Client cached an ID from a canceled/purged subscription; mixing up providerSubscriptionId and internal id; database migration or environment mismatch; calling cancel twice after the record was removed.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/538d5e5d9a011d6a.
Report an issue: GitHub.