Stirling-Tools/Stirling-PDF · error · Error
License key missing. Please contact support.
Error message
License key missing. Please contact support.
What it means
Thrown by AdminPlanSection.handleManageClick when the license is PRO/ENTERPRISE but licenseInfo.licenseKey is missing. This is an inconsistent state: the system recognizes a paid license type but has no corresponding key to authenticate the billing-portal session request.
Source
Thrown at frontend/editor/src/proprietary/components/shared/config/configSections/AdminPlanSection.tsx:72
{ 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);
alert({
alertType: "error",
title: t("billing.portal.error", "Failed to open billing portal"),
body:
(error instanceof Error ? error.message : undefined) ||
"Please try again or contact support.",View on GitHub (pinned to 9ef20dcab8)
Solutions
- Re-fetch full license info (including key) from the server and re-persist.
- Validate license record integrity on load — ensure both licenseType and licenseKey are present together.
- On this error, offer a 'Re-sync license' action that re-pulls the license from the backend.
Example fix
// before
if (!licenseInfo?.licenseKey) {
throw new Error("License key missing. Please contact support.");
}
// after — treat as recoverable data integrity issue
if (!licenseInfo?.licenseKey) {
await licenseService.refreshLicense();
const fresh = await licenseService.getLicenseInfo();
if (!fresh?.licenseKey) {
alert({ alertType: "error", title: t("license.keyMissing", "License key missing. Please contact support.") });
return;
}
} Defensive patterns
Strategy: fallback
Validate before calling
// Validate license record integrity on load
if (licenseInfo?.licenseType && licenseInfo.licenseType !== "NORMAL" && !licenseInfo.licenseKey) {
await licenseService.refreshLicense(); // re-pull from server
} Type guard
function isCompleteLicense(info: { licenseType?: string; licenseKey?: string }): boolean {
return !!info.licenseType && !!info.licenseKey;
} Prevention
- Treat a license record with a type but no key as a data-integrity defect and re-sync.
- Persist license records atomically (type + key together).
- Validate license record shape on load and alert on inconsistency.
When it happens
Trigger: licenseType is set to PRO/ENTERPRISE but licenseKey is null/undefined/empty. Partial or corrupted license data in storage. License type was set server-side but the key was never persisted locally.
Common situations: Corrupted license record in local storage. Migration issue where licenseType migrated but licenseKey did not. Race condition reading license info before the key was persisted.
Related errors
- No pricing data returned
- No billing portal URL returned
- No license key found. Please activate a license first.
- No valid license found. Please purchase a license before acc
- Supabase is not configured. Please use static plans instead.
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/0801bf5c0d6aa5b9.
Report an issue: GitHub.