Stirling-Tools/Stirling-PDF · warning · Error
No valid license found. Please purchase a license before acc
Error message
No valid license found. Please purchase a license before accessing the billing portal.
What it means
Thrown by AdminPlanSection.handleManageClick when the user's license is absent, falsy, or 'NORMAL' (free tier). Only PRO or ENTERPRISE licenses are permitted to open the billing portal — the portal is for managing paid subscriptions, not for free-tier users.
Source
Thrown at frontend/editor/src/proprietary/components/shared/config/configSections/AdminPlanSection.tsx:66
{ value: "gbp", label: "British pound (GBP, £)" },
{ value: "usd", label: "US dollar (USD, $)" },
{ value: "eur", label: "Euro (EUR, €)" },
{ value: "cny", label: "Chinese yuan (CNY, ¥)" },
{ value: "inr", label: "Indian rupee (INR, ₹)" },
{ value: "brl", label: "Brazilian real (BRL, R$)" },
{ value: "idr", label: "Indonesian rupiah (IDR, Rp)" },
];
const handleManageClick = useCallback(async () => {
// Block access if login is disabled
if (!validateLoginEnabled()) {
return;
}
try {
// Only allow PRO or ENTERPRISE licenses to access billing portal
if (!licenseInfo?.licenseType || licenseInfo.licenseType === "NORMAL") {
throw new Error(
"No valid license found. Please purchase a license before accessing the billing portal.",
);
}
if (!licenseInfo?.licenseKey) {
throw new Error("License key missing. Please contact support.");
}
// Create billing portal session with license key
const response = await licenseService.createBillingPortalSession(
window.location.href,
licenseInfo.licenseKey,
);
// Open billing portal in new tab
window.open(response.url, "_blank");
} catch (error: unknown) {
console.error("Failed to open billing portal:", error);View on GitHub (pinned to 9ef20dcab8)
Solutions
- Hide the Manage Billing control entirely when licenseType is missing or 'NORMAL'.
- Show an 'Upgrade' CTA instead of the Manage Billing button for free-tier users.
- Ensure licenseInfo is loaded and refreshed before rendering the section.
Example fix
// before
if (!licenseInfo?.licenseType || licenseInfo.licenseType === "NORMAL") {
throw new Error("No valid license found. ...");
}
// after — gate the UI
const canManageBilling =
!!licenseInfo?.licenseType && licenseInfo.licenseType !== "NORMAL";
return canManageBilling ? <ManageBillingButton /> : <UpgradePrompt />; Defensive patterns
Strategy: validation
Validate before calling
const isPaidLicense = !!licenseInfo?.licenseType && licenseInfo.licenseType !== "NORMAL"; // Only render Manage Billing when isPaidLicense is true
Type guard
function isPaidLicenseType(type: unknown): boolean {
return typeof type === "string" && type !== "NORMAL" && type.length > 0;
} Prevention
- Render Manage Billing only for PRO/ENTERPRISE licenses.
- Show an Upgrade CTA for free-tier users instead.
- Ensure licenseInfo is loaded before rendering the section.
When it happens
Trigger: User with no licenseType, a falsy licenseType, or licenseType === 'NORMAL' clicks the Manage Billing control in the admin plan section.
Common situations: A free/NORMAL user reaches the admin config and tries to manage billing. License info failed to load (undefined). User downgraded to free and the cached licenseType is stale.
Related errors
- No license key found. Please activate a license first.
- License key missing. Please contact support.
- No team resolved yet
- Member has no backend identity
- Unknown policy category: ${id}
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/ff53ea9e8dd651f0.
Report an issue: GitHub.