different-ai/openwork · error

t("providers.provider_id_required")

Error message

t("providers.provider_id_required")

What it means

startProviderOAuth accepts an optional providerId; when it is omitted, empty, or whitespace-only, the store cannot determine which provider to authenticate and throws providers.provider_id_required. The store intentionally does not guess or default to the first provider.

Source

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

  ): Promise<ProviderOAuthStartResult> {
    setStateField("providerAuthError", null);
    const c = options.client();
    if (!c) {
      throw new Error(t("providers.not_connected"));
    }
    try {
      const cachedMethods = state.providerAuthMethods;
      const authMethods = Object.keys(cachedMethods).length
        ? cachedMethods
        : await loadProviderAuthMethods(getProviderAuthWorkerType());
      const providerIds = Object.keys(authMethods).sort();
      if (!providerIds.length) {
        throw new Error(t("providers.no_providers_available"));
      }

      const resolved = providerId?.trim() ?? "";
      if (!resolved) {
        throw new Error(t("providers.provider_id_required"));
      }
      assertProviderAllowedByDesktopPolicy(resolved);

      const methods = authMethods[resolved];
      if (!methods || !methods.length) {
        throw new Error(`${t("providers.unknown_provider")}: ${resolved}`);
      }

      const oauthIndex =
        methodIndex !== undefined
          ? methodIndex
          : methods.find((method) => method.type === "oauth")?.methodIndex ?? -1;
      if (oauthIndex === -1) {
        throw new Error(
          `${t("providers.no_oauth_prefix")} ${resolved}. ${t("providers.use_api_key_suffix")}`,
        );
      }

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Pass a non-empty providerId to startProviderOAuth, resolved from the user's selection.
  2. Fix the UI state so the provider selection is always set before the action is callable (disable the button until a provider is chosen).
  3. Check for a mapping bug where the stored provider name is trimmed to empty.
  4. In tests, pass an explicit providerId like 'anthropic' instead of relying on defaults.

Example fix

// before
await startProviderOAuth(selectedProviderId); // selectedProviderId may be ""
// after
if (!selectedProviderId?.trim()) return;
await startProviderOAuth(selectedProviderId.trim());
Defensive patterns

Strategy: validation

Validate before calling

const resolved = selectedProviderId?.trim();
if (!resolved) {
  showToast("Select a provider first.");
  return;
}
await store.startProviderOAuth(resolved);

Type guard

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

Try / catch

try {
  await store.startProviderOAuth(providerId);
} catch (e) {
  if (e instanceof Error && /provider.?id.?required/i.test(e.message)) {
    focusProviderSelector();
  } else throw e;
}

Prevention

When it happens

Trigger: Calling startProviderOAuth with providerId === undefined, or a string that is empty/whitespace after .trim() — e.g. startProviderOAuth(undefined), startProviderOAuth(""), startProviderOAuth(" ").

Common situations: UI wiring bug where the selected provider binding is empty (unselected dropdown); a caller passing a variable that was never initialized; programmatic callers/tests invoking the action without arguments; form state cleared before submit.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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