{"record":{"id":"7efd79f0808522c8","repo":"FlowiseAI/Flowise","slug":"stripe-is-not-initialized","errorCode":null,"errorMessage":"Stripe is not initialized","messagePattern":"Stripe is not initialized","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/server/src/StripeManager.ts","lineNumber":30,"sourceCode":"    private cacheManager: UsageCacheManager\n\n    public static async getInstance(): Promise<StripeManager> {\n        if (!StripeManager.instance) {\n            StripeManager.instance = new StripeManager()\n            await StripeManager.instance.initialize()\n        }\n        return StripeManager.instance\n    }\n\n    private async initialize() {\n        if (!this.stripe && process.env.STRIPE_SECRET_KEY) {\n            this.stripe = new Stripe(process.env.STRIPE_SECRET_KEY)\n        }\n        this.cacheManager = await UsageCacheManager.getInstance()\n    }\n\n    public getStripe() {\n        if (!this.stripe) throw new Error('Stripe is not initialized')\n        return this.stripe\n    }\n\n    public getSubscriptionObject(subscription: Stripe.Response<Stripe.Subscription>) {\n        return {\n            customer: subscription.customer,\n            status: subscription.status,\n            created: subscription.created\n        }\n    }\n\n    public async getProductIdFromSubscription(subscriptionId: string) {\n        if (!subscriptionId || subscriptionId.trim() === '') {\n            return ''\n        }\n\n        if (!this.stripe) {\n            throw new Error('Stripe is not initialized')","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/server/src/StripeManager.ts#L12-L48","documentation":"StripeManager is a singleton that lazily constructs the Stripe SDK client inside initialize(), but only when process.env.STRIPE_SECRET_KEY is set. getStripe() returns the cached client and throws this generic Error if the client was never constructed. Because nearly every billing method delegates through getStripe(), this surfaces wherever Stripe is first touched in a misconfigured environment.","triggerScenarios":"Any call path reaching getStripe() (getProductIdFromSubscription, createStripeCustomerPortalSession, getAdditionalSeatsQuantity, etc.) while STRIPE_SECRET_KEY is unset, empty, or loaded after getInstance() ran. Running the server with the wrong NODE_ENV that doesn't load the billing env file. Stripe-only code paths invoked in a self-hosted OSS deployment that intentionally omits Stripe.","commonSituations":"Missing .env entry for STRIPE_SECRET_KEY. Env loaded asynchronously but getInstance() cached an uninitialized instance before vars were available. Copying config between environments and dropping the Stripe key. Feature flags enabling cloud billing code in a non-cloud build.","solutions":["Set STRIPE_SECRET_KEY in the active environment (sk_test_... or sk_live_...) and restart the process so initialize() constructs the client.","Verify the env file is actually loaded for the running NODE_ENV before StripeManager.getInstance() is first called.","If Stripe is optional for your deployment, guard the calling code path so billing routes aren't registered/invoked when the key is absent.","Reset the singleton in tests (or restart) after injecting the key, since the cached instance won't reinitialize on its own."],"exampleFix":"// before\npublic getStripe() {\n    if (!this.stripe) throw new Error('Stripe is not initialized')\n    return this.stripe\n}\n\n// after: explain the root cause\npublic getStripe() {\n    if (!this.stripe) {\n        throw new Error('Stripe is not initialized. Set STRIPE_SECRET_KEY and restart before calling billing APIs.')\n    }\n    return this.stripe\n}","handlingStrategy":"validation","validationCode":"// At boot, fail fast if Stripe is required but unconfigured\nfunction requireStripeKey() {\n    if (!process.env.STRIPE_SECRET_KEY) {\n        throw new Error('STRIPE_SECRET_KEY is not set. Configure it before enabling billing routes.')\n    }\n}\n\n// only register billing routes when the key is present\nif (process.env.STRIPE_SECRET_KEY) {\n    app.use('/billing', billingRouter)\n} else {\n    logger.warn('Stripe disabled: STRIPE_SECRET_KEY not set')\n}","typeGuard":"function isStripeInitialized(mgr: StripeManager): boolean {\n    // getStripe throws when uninitialized; probe safely instead\n    try {\n        mgr.getStripe()\n        return true\n    } catch {\n        return false\n    }\n}","tryCatchPattern":"try {\n    const stripe = stripeManager.getStripe()\n} catch (err) {\n    if (err instanceof Error && err.message === 'Stripe is not initialized') {\n        return res.status(StatusCodes.SERVICE_UNAVAILABLE).json({ error: 'Billing is not configured on this server' })\n    }\n    throw err\n}","preventionTips":["Set STRIPE_SECRET_KEY in every environment that registers billing routes.","Confirm env files load before StripeManager.getInstance() is first awaited.","Conditionally register billing routes only when the key is present.","In tests, inject a mock Stripe client or reset the singleton after setting the key."],"tags":["stripe","configuration","env-vars","singleton","billing"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}