Problem
Some pages call toast.error() directly in the component body when a React Query error flag is set (isError, costError, etc.).
Render can run many times while the error is still true. Each render fires another toast, so users see duplicate or stacked messages.
Verified on API Keys page
src/pages/developer/developer.tsx:
if (isError) {
toast.error(t('apiKeys.toastFetchError'));
}
When the secret-keys request fails:
- One or more "Error fetching secret keys" toasts appear.
- React logs:
Cannot update a component ('HotToaster') while rendering a different component ('DeveloperPage').
- Opening Add (or any re-render while
isError is still true) can show another identical toast.
Steps to reproduce
- Break the secret-keys API request (block in DevTools or bad API URL).
- Go to Developers → API Keys.
- See the error toast.
- Click Add — another identical toast appears.
Fix
Move the toast into useEffect, matching existing code in SettingsDashboard.tsx and InvoicesWidget.tsx:
useEffect(() => {
if (isError) {
toast.error(t('apiKeys.toastFetchError'));
}
}, [isError, t]);
Affected files
Main issue (~26 files): error toast in render when a query fails.
Includes: developer.tsx, ServiceAccounts.tsx, Billing.tsx, WebhookDashboard.tsx, CostAnalytics.tsx, Pricing.tsx, PlanDetailsPage.tsx, plan tabs (PlanEntitlementsTab, PlanCreditGrantsTab, PlanInformationTab), FeatureDetails.tsx, CouponDetails.tsx, CostSheetDetails.tsx, AddonDetails.tsx, tax pages, PaymentList.tsx, credit note pages, CustomerWalletTab.tsx, CustomerTaxAssociationTab.tsx, CustomerOverviewTab.tsx, CustomerInvoiceDetail.tsx, CustomerSubscriptionDetailsPage.tsx, InvoicesTab.tsx, WalletTab.tsx (2 call sites).
Follow-up: a few detail pages also toast in render when data is missing (!planData, !coupon, etc.) even without isError — worth splitting from the query-error fix.
Not affected: pages that already use useEffect or mutation onError callbacks.
Acceptance criteria

Problem
Some pages call
toast.error()directly in the component body when a React Query error flag is set (isError,costError, etc.).Render can run many times while the error is still true. Each render fires another toast, so users see duplicate or stacked messages.
Verified on API Keys page
src/pages/developer/developer.tsx:When the secret-keys request fails:
Cannot update a component ('HotToaster') while rendering a different component ('DeveloperPage').isErroris still true) can show another identical toast.Steps to reproduce
Fix
Move the toast into
useEffect, matching existing code inSettingsDashboard.tsxandInvoicesWidget.tsx:Affected files
Main issue (~26 files): error toast in render when a query fails.
Includes:
developer.tsx,ServiceAccounts.tsx,Billing.tsx,WebhookDashboard.tsx,CostAnalytics.tsx,Pricing.tsx,PlanDetailsPage.tsx, plan tabs (PlanEntitlementsTab,PlanCreditGrantsTab,PlanInformationTab),FeatureDetails.tsx,CouponDetails.tsx,CostSheetDetails.tsx,AddonDetails.tsx, tax pages,PaymentList.tsx, credit note pages,CustomerWalletTab.tsx,CustomerTaxAssociationTab.tsx,CustomerOverviewTab.tsx,CustomerInvoiceDetail.tsx,CustomerSubscriptionDetailsPage.tsx,InvoicesTab.tsx,WalletTab.tsx(2 call sites).Follow-up: a few detail pages also toast in render when data is missing (
!planData,!coupon, etc.) even withoutisError— worth splitting from the query-error fix.Not affected: pages that already use
useEffector mutationonErrorcallbacks.Acceptance criteria
toast.error()in render for query errorsHotToasterrender warning in the console