Stirling-Tools/Stirling-PDF · error · Error

Failed to check license key: ${error.message}

Error message

Failed to check license key: ${error.message}

What it means

Thrown by checkLicenseKey when supabase.functions.invoke('get-license-key', ...) returns a non-null error. The get-license-key edge function maps an installation_id to a license record; a returned error means the function failed — invalid installation_id, backend DB error, missing secrets, or a function exception. error.message is wrapped for the caller.

Source

Thrown at frontend/editor/src/proprietary/services/licenseService.ts:442

  /**
   * Check if license key is ready for the given installation ID
   */
  async checkLicenseKey(installationId: string): Promise<LicenseKeyResponse> {
    // Check if Supabase is configured
    if (!isSupabaseConfigured || !supabase) {
      throw new Error(
        "Supabase is not configured. License key lookup is not available.",
      );
    }

    const { data, error } = await supabase.functions.invoke("get-license-key", {
      body: {
        installation_id: installationId,
      },
    });

    if (error) {
      throw new Error(`Failed to check license key: ${error.message}`);
    }

    return data as LicenseKeyResponse;
  },

  /**
   * Save license key to backend
   */
  async saveLicenseKey(licenseKey: string): Promise<LicenseSaveResponse> {
    try {
      const response = await apiClient.post("/api/v1/admin/license-key", {
        licenseKey: licenseKey,
      });

      return response.data;
    } catch (error) {
      console.error("Error saving license key:", error);
      throw error;

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Read error.message to determine whether it's an input (installation_id) or backend problem.
  2. Confirm getInstallationId() returns a real MAC-based fingerprint before calling checkLicenseKey.
  3. Verify the get-license-key function is deployed with its required secrets.
  4. Retry after a short delay if the purchase webhook may not have settled yet.

Example fix

// before
const res = await licenseService.checkLicenseKey(installationId);

// after
try {
  const res = await licenseService.checkLicenseKey(installationId);
  if (res.status === 'pending') pollShortly();
} catch (e) {
  showToast(e instanceof Error ? e.message : 'License lookup failed');
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!installationId || installationId === 'unknown') {
  setError('Installation ID not available yet');
  return;
}

Type guard

export function isValidInstallationId(id: string): boolean {
  return typeof id === 'string' && id.length > 0 && id !== 'unknown';
}

Try / catch

try {
  const res = await licenseService.checkLicenseKey(installationId);
  if (res.status === 'pending') setTimeout(retry, 3000);
} catch (e) {
  showToast(e instanceof Error ? e.message : 'License lookup failed');
}

Prevention

When it happens

Trigger: installation_id is empty/malformed; the function can't reach its data store; function deployed without required secrets; the installation has no purchase associated and the function surfaces that as an error rather than {status:'pending'}.

Common situations: getInstallationId returned an unexpected value (e.g. 'unknown'); edge function misconfigured; Supabase project paused; race where activation is checked before the purchase webhook completes.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/a5358020f83d2887. Report an issue: GitHub.