FlowiseAI/Flowise · error · Error

No subscription items found

Error message

No subscription items found

What it means

Thrown by IdentityManager.updateAdditionalSeats() after a successful Stripe updateAdditionalSeats call, when subscription.items.data is an empty array. The code assumes at least one line item exists so it can read items[0].price.product to fetch product metadata and quotas; with no items it cannot derive a productId and aborts. This indicates the Stripe subscription returned from the update call has no line items, which is an unexpected Stripe state.

Source

Thrown at packages/server/src/IdentityManager.ts:349

        if (!subscriptionId) return {}
        if (!this.stripeManager) {
            throw new Error('Stripe manager is not initialized')
        }
        return await this.stripeManager.getAdditionalSeatsProration(subscriptionId, newQuantity)
    }

    public async updateAdditionalSeats(subscriptionId: string, quantity: number, prorationDate: number) {
        if (!subscriptionId) return {}

        if (!this.stripeManager) {
            throw new Error('Stripe manager is not initialized')
        }
        const { success, subscription, invoice } = await this.stripeManager.updateAdditionalSeats(subscriptionId, quantity, prorationDate)

        // Fetch product details to get quotas
        const items = subscription.items.data
        if (items.length === 0) {
            throw new Error('No subscription items found')
        }

        const productId = items[0].price.product as string
        const product = await this.stripeManager.getStripe().products.retrieve(productId)
        const productMetadata = product.metadata

        // Extract quotas from metadata
        const quotas: Record<string, number> = {}
        for (const key in productMetadata) {
            if (key.startsWith('quota:')) {
                quotas[key] = parseInt(productMetadata[key])
            }
        }
        quotas[LICENSE_QUOTAS.ADDITIONAL_SEATS_LIMIT] = quantity

        // Get features from Stripe
        const features = await this.getFeaturesByPlan(subscription.id, true)

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Before calling updateAdditionalSeats, verify the subscription has active items (e.g. retrieve it and check items.data.length).
  2. Handle the empty-items case explicitly: return a structured error to the client instead of throwing, if business logic permits.
  3. Re-fetch the subscription and retry if the empty state is transient (e.g. concurrent Stripe webhook).
  4. Inspect the subscription in the Stripe dashboard to confirm its current item state.

Example fix

// before
const items = subscription.items.data
if (items.length === 0) throw new Error('No subscription items found')
const productId = items[0].price.product as string

// after
const items = subscription.items.data
if (items.length === 0) {
    return { success: false, message: 'Subscription has no items; cannot update seats' }
}
const productId = items[0].price.product as string
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-fetch the subscription and confirm it has items before the seats update
const sub = await stripeManager.getStripe().subscriptions.retrieve(subId)
if (!sub.items.data.length) {
    return res.status(409).json({ message: 'Subscription has no items; cannot update seats' })
}

Type guard

const subscriptionHasItems = (sub: { items: { data: unknown[] } }): boolean =>
    Array.isArray(sub.items.data) && sub.items.data.length > 0

Try / catch

try {
    const result = await identityManager.updateAdditionalSeats(subId, qty, prorationDate)
} catch (e) {
    if ((e as Error).message === 'No subscription items found') {
        // data integrity issue — re-fetch to confirm, then surface a 409 or retry once
        return res.status(409).json({ message: 'Subscription has no items' })
    }
    throw e
}

Prevention

When it happens

Trigger: A subscription whose items were all removed/zeroed just before or during the seats update, so the returned subscription object has items.data.length === 0; a subscription in an incomplete/canceled state with no active items; a Stripe test fixture returning an empty items array.

Common situations: A subscription that was canceled or drained of items out-of-band; a race between a cancellation webhook and the seats update; misconfigured Stripe test data; a subscription created without any item.

Related errors


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/1562020c2d4fd698. Report an issue: GitHub.