different-ai/openwork · error

t("providers.api_key_required")

Error message

t("providers.api_key_required")

What it means

submitProviderApiKey validates the apiKey argument and throws when the trimmed value is empty. A blank key can never authenticate, so the store rejects it up front with the providers.api_key_required message.

Source

Thrown at apps/app/src/react-app/domains/connections/provider-auth/store.ts:1632

        }
        return { connected: false, pending: true };
      }
      const message = describeProviderError(error, t("providers.oauth_failed"));
      setStateField("providerAuthError", message);
      throw error instanceof Error ? error : new Error(message);
    }
  }

  async function submitProviderApiKey(providerId: string, apiKey: string) {
    setStateField("providerAuthError", null);
    const c = options.client();
    if (!c) {
      throw new Error(t("providers.not_connected"));
    }

    const trimmed = apiKey.trim();
    if (!trimmed) {
      throw new Error(t("providers.api_key_required"));
    }
    assertProviderAllowedByDesktopPolicy(providerId);

    setStateField("providerAuthBusy", true);
    try {
      if (providerId.trim().toLowerCase() === DESKTOP_RESTRICTION_OPENCODE_PROVIDER_ID) {
        await ensureProjectProviderDisabledState(providerId, false);
      }
      await c.auth.set({ providerID: providerId, auth: { type: "api", key: trimmed } });
      await refreshProviders({ dispose: true });
      return `${t("status.connected")} ${providerId}`;
    } catch (error) {
      const message = describeProviderError(error, t("providers.save_api_key_failed"));
      setStateField("providerAuthError", message);
      throw error instanceof Error ? error : new Error(message);
    } finally {
      setStateField("providerAuthBusy", false);
    }

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Trim and check the key in the UI before calling: if (!apiKey.trim()) show a validation message.
  2. Add required/minLength validation on the API key input field.
  3. Disable the submit button until the field contains non-whitespace content.
  4. If the key is read from env/config, verify that source actually has a value.

Example fix

// before
await store.submitProviderApiKey(providerId, formData.apiKey);
// after
const key = formData.apiKey.trim();
if (!key) return showError("API key is required");
await store.submitProviderApiKey(providerId, key);
Defensive patterns

Strategy: validation

Validate before calling

const trimmed = apiKey.trim();
if (!trimmed) throw new Error("API key required before submit");

Type guard

function isNonEmptyString(v: unknown): v is string {
  return typeof v === "string" && v.trim().length > 0;
}

Try / catch

try {
  await store.submitProviderApiKey(providerId, apiKey);
} catch (e) {
  if (String((e as Error).message).includes("api_key_required")) {
    focusApiKeyFieldWithError();
  }
}

Prevention

When it happens

Trigger: Calling submitProviderApiKey with "", " ", or a value bound to an empty input field; pasting nothing into the key dialog and submitting.

Common situations: User clicks Save with an empty input before client-side validation; clipboard paste failed silently; form state reset between render and submit.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/00da61ae1cda0351. Report an issue: GitHub.