{"record":{"id":"861beda3b1e6e51f","repo":"Stirling-Tools/Stirling-PDF","slug":"supabase-is-not-configured-please-use-static-plan","errorCode":null,"errorMessage":"Supabase is not configured. Please use static plans instead.","messagePattern":"Supabase is not configured\\. Please use static plans instead\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"frontend/editor/src/proprietary/services/licenseService.ts","lineNumber":123,"sourceCode":"\nconst licenseService = {\n  /**\n   * Get available plans with pricing for the specified currency.\n   *\n   * Feature and highlight labels are passed in by the caller (a React hook /\n   * context that resolves them via `usePlanFeatures` / `usePlanHighlights`),\n   * which keeps this service free of React/i18n dependencies while still\n   * returning fully localized plan content.\n   */\n  async getPlans(\n    planFeatures: PlanFeaturesMap,\n    planHighlights: PlanHighlightsMap,\n    currency: string = \"usd\",\n  ): Promise<PlansResponse> {\n    try {\n      // Check if Supabase is configured\n      if (!isSupabaseConfigured || !supabase) {\n        throw new Error(\n          \"Supabase is not configured. Please use static plans instead.\",\n        );\n      }\n\n      // Fetch all self-hosted prices from Stripe\n      const { data, error } = await supabase.functions.invoke<{\n        prices: Record<\n          string,\n          {\n            unit_amount: number;\n            currency: string;\n            lookup_key: string;\n          }\n        >;\n        missing: string[];\n      }>(\"stripe-price-lookup\", {\n        body: {\n          lookup_keys: SELF_HOSTED_LOOKUP_KEYS,","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/proprietary/services/licenseService.ts#L105-L141","documentation":"Thrown by licenseService.getPlans when Supabase isn't configured (isSupabaseConfigured is false or the supabase client is null). Plans/pricing are fetched live from Stripe via a Supabase edge function (stripe-price-lookup), so without Supabase the dynamic pricing path is impossible. The message explicitly points callers to the static plans fallback so the UI can still render tiers.","triggerScenarios":"getPlans() called in a self-hosted build without Supabase env vars set; the supabaseClient module's isSupabaseConfigured flag is false because VITE_SUPABASE_URL/KEY are missing; calling getPlans in a build flavor that intentionally omits Supabase.","commonSituations":"Self-hosted deploy without the Supabase env vars configured; dev running the editor without a .env.local containing the Supabase keys; an OSS/core build that shouldn't hit licensing at all.","solutions":["Catch the error and fall back to the static plan definitions (the message tells you to), as the caller (usePlanFeatures/usePlanHighlights context) is expected to do.","Set VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY in the active env layer if you want live Stripe pricing.","Gate the dynamic-pricing UI behind isSupabaseConfigured so getPlans is only called when it can succeed."],"exampleFix":"// before\nconst { plans } = await licenseService.getPlans(features, highlights);\n\n// after\nlet plans;\ntry {\n  ({ plans } = await licenseService.getPlans(features, highlights));\n} catch (e) {\n  if (/not configured/i.test(e.message)) plans = STATIC_PLANS;\n  else throw e;\n}","handlingStrategy":"validation","validationCode":"import { isSupabaseConfigured } from \"@app/services/supabaseClient\";\n\nif (!isSupabaseConfigured) {\n  // use static plans; don't call getPlans\n}","typeGuard":"export function canFetchDynamicPlans(): boolean {\n  return isSupabaseConfigured;\n}","tryCatchPattern":"try {\n  return await licenseService.getPlans(features, highlights, currency);\n} catch (e) {\n  if (/not configured/i.test(e instanceof Error ? e.message : \"\")) {\n    return { plans: STATIC_PLANS };\n  }\n  throw e;\n}","preventionTips":["Gate the dynamic-pricing code path on isSupabaseConfigured.","Always implement the static-plans fallback the error message directs you to.","Keep VITE_SUPABASE_URL/VITE_SUPABASE_ANON_KEY in the committed mode env files for self-hosted builds that need live pricing."],"tags":["supabase","license","plans","stripe","configuration","proprietary","typescript"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}