fix(billing): avoid crash when billingPlanDetails is undefined in ContainerButton#2999
Conversation
…ng in ContainerButton Self-hosted deployments populate organization but leave billingPlanDetails undefined (there is no billing plan). ContainerButton precomputes the default tooltipContent at component instantiation with organization?.billingPlanDetails.group and billingPlanDetails.name, so the moment any page that renders a ContainerButton (e.g. Project > Functions > Templates) loads on self-hosted, Svelte throws a TypeError and the rest of the view blanks out. This was already observed on the Auth Security page and addressed there in appwrite#2958; the same pattern is still live in containerButton.svelte for every other consumer. Switch both property reads to optional chaining so the tooltip falls back gracefully on self-hosted. Fixes appwrite#2975.
Greptile SummaryAdds optional chaining to two Confidence Score: 5/5Safe to merge — minimal, targeted fix with no behavior change on cloud and correct crash prevention on self-hosted. Only two characters changed (two No files require special attention. Important Files Changed
Reviews (1): Last reviewed commit: "fix(billing): don't access billingPlanDe..." | Re-trigger Greptile |
Fixes #2975.
Symptom
On Appwrite 1.9.0 self-hosted, opening Project > Functions > Templates blanks the page with:
The same stack trace was previously reported against Auth Security and fixed by #2958; the underlying source still lives in
src/lib/layout/containerButton.svelte, which is also used by the Functions Templates page and several other surfaces, so the bug resurfaces there.Root cause
ContainerButtoncomputes its defaulttooltipContentat component instantiation:export let tooltipContent = $organization?.billingPlanDetails.group === BillingPlanGroup.Starter ? `Upgrade to add more ${title.toLocaleLowerCase()}` : `You've reached the ${title.toLocaleLowerCase()} limit for the ${ $organization?.billingPlanDetails.name } plan`;On self-hosted deployments,
organizationis populated butbillingPlanDetailsisundefined(there's no billing system). The optional chain stops atorganization, but.billingPlanDetails.group/.billingPlanDetails.nameare direct property reads, so the expression throws the moment any page containing aContainerButtonmounts.Fix
Promote both property reads to optional chaining:
On cloud, behaviour is unchanged --
billingPlanDetailsis always populated, both reads resolve normally. On self-hosted,groupbecomesundefined(falling through to the plan-limit branch withundefinedin place of the plan name), but the tooltip is only shown when the wrappingdisabledprop is true, which self-hosted never hits via this path, so the cosmetic fallback is acceptable and the crash is gone.