FlowiseAI/Flowise · error · InternalFlowiseError
Subscription is canceled
Error message
Subscription is canceled
What it means
Inside getProductIdFromSubscription, after a cache miss the subscription is retrieved from Stripe. If its status is 'canceled', an InternalFlowiseError with HTTP 401 UNAUTHORIZED is thrown. This treats a canceled subscription as an authorization failure: the caller is not entitled to resolve a product for it. The surrounding try/catch swallows all errors and returns '' here, so in this specific method the throw is caught and converted to an empty string.
Source
Thrown at packages/server/src/StripeManager.ts:58
}
public async getProductIdFromSubscription(subscriptionId: string) {
if (!subscriptionId || subscriptionId.trim() === '') {
return ''
}
if (!this.stripe) {
throw new Error('Stripe is not initialized')
}
const subscriptionData = await this.cacheManager.getSubscriptionDataFromCache(subscriptionId)
if (subscriptionData?.productId) {
return subscriptionData.productId
}
try {
const subscription = await this.stripe.subscriptions.retrieve(subscriptionId)
if (subscription.status === 'canceled') throw new InternalFlowiseError(StatusCodes.UNAUTHORIZED, 'Subscription is canceled')
const items = subscription.items.data
if (items.length === 0) {
return ''
}
const productId = items[0].price.product as string
await this.cacheManager.updateSubscriptionDataToCache(subscriptionId, {
productId,
subsriptionDetails: this.getSubscriptionObject(subscription)
})
return productId
} catch (error) {
return ''
}
}
public async getFeaturesByPlan(subscriptionId: string, withoutCache: boolean = false) {View on GitHub (pinned to abe4a8601a)
Solutions
- Stop calling billing-dependent APIs for subscriptions known to be canceled (filter by status upstream).
- If an empty product response is acceptable, rely on the method's own catch (it returns '' on any error) rather than treating the throw as fatal in the caller.
- Reconcile cached subscription status so canceled IDs are short-circuited before the Stripe retrieve.
- For genuine re-activation flows, create a new subscription rather than reusing the canceled ID.
Example fix
// before: canceled subscription throws, but caller may not expect it const subscription = await this.stripe.subscriptions.retrieve(subscriptionId) if (subscription.status === 'canceled') throw new InternalFlowiseError(StatusCodes.UNAUTHORIZED, 'Subscription is canceled') // after: short-circuit on canceled status without a throw inside the swallowed try if (subscription.status === 'canceled') return ''
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check subscription status before relying on the product ID
const sub = await stripeManager.getStripe().subscriptions.retrieve(subscriptionId)
if (sub.status === 'canceled') {
// skip product-dependent logic
return ''
} Type guard
function isSubscriptionActive(status: Stripe.Subscription.Status): boolean {
return status !== 'canceled'
} Try / catch
// getProductIdFromSubscription swallows errors and returns '' here, so callers
// should treat '' as 'unknown/canceled' rather than catching:
const productId = await stripeManager.getProductIdFromSubscription(subscriptionId)
if (!productId) {
// handle canceled/unknown subscription without throwing Prevention
- Treat an empty product ID result from getProductIdFromSubscription as a canceled/unknown subscription.
- Cache canceled status so repeated calls don't re-hit Stripe.
- Filter canceled subscription IDs out of batch jobs.
- Reconcile subscription status on cancellation webhooks.
When it happens
Trigger: Passing a subscription ID whose Stripe status is 'canceled' into getProductIdFromSubscription. This happens for ex-customers, after a plan cancellation completes, or when a webhook/job retries against a stale subscription ID.
Common situations: User cancelled their plan and a background job still references the old subscription. Test fixtures using a canceled test subscription. Race where cancellation webhook lands before an in-flight request completes.
Related errors
- Subscription is canceled
- Stripe manager is not initialized
- No subscription items found
- Subscription ID is required
- No active price found for the product
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/26db7edf59e19639.
Report an issue: GitHub.