different-ai/openwork · error · Error

Failed to delete provider (${response.status}).

Error message

Failed to delete provider (${response.status}).

What it means

Thrown by deleteProvider in llm-provider-detail-screen.tsx when DELETE /v1/llm-providers/{id} (12s timeout) returns anything other than 204 or an ok status. getRequestError (den-flow.ts:527) wraps the server payload: 403 {error:'reauth'} becomes ReauthRequiredError, otherwise the message is the server `error` text or "Failed to delete provider (<status>).".

Source

Thrown at ee/apps/den-web/app/(den)/dashboard/_components/llm-provider-detail-screen.tsx:77

            !window.confirm(
                `Delete ${provider.name}? This will remove its saved model list and access rules.`,
            )
        ) {
            return;
        }

        setDeleteError(null);
        try {
            await runReauthableAction("delete-llm-provider", async () => {
                setDeleteBusy(true);
                const { response, payload } = await requestJson(
                    `/v1/llm-providers/${encodeURIComponent(provider.id)}`,
                    { method: "DELETE" },
                    12000,
                );

                if (response.status !== 204 && !response.ok) {
                    throw getRequestError(payload, response, `Failed to delete provider (${response.status}).`);
                }

                await reloadProviders();
                router.push(getLlmProvidersRoute(orgSlug));
                router.refresh();
            });
        } catch (nextError) {
            setDeleteError(
                nextError instanceof Error
                    ? nextError.message
                    : "Could not delete the provider.",
            );
        } finally {
            setDeleteBusy(false);
        }
    }

    if (busy && !provider) {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. On 404, proceed as if deleted: refresh the providers list and navigate to the providers route.
  2. On 400/409, detach workers, automations, or policies referencing the provider before deleting.
  3. Verify the user has owner/admin org role for 401/403, and complete reauth when isReauthRequiredError is true.
  4. If the provider is managed/built-in, disable it instead of deleting.

Example fix

// before
if (response.status !== 204 && !response.ok) {
  throw getRequestError(payload, response, `Failed to delete provider (${response.status}).`);
}
// after
if (response.status !== 204 && !response.ok) {
  if (response.status === 404) {
    await reloadProviders();
    router.push(getLlmProvidersRoute(orgSlug));
    return;
  }
  throw getRequestError(payload, response, `Failed to delete provider (${response.status}).`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before deleting
if (!provider?.id) throw new Error("No provider selected.");
if (!hasOrgAdminRole(userRole)) throw new Error("Only owners/admins can delete providers.");
if (provider.managed) throw new Error("Built-in providers cannot be deleted.");

Type guard

function isReauthError(e: unknown): e is ReauthRequiredError {
  return e instanceof ReauthRequiredError;
}

Try / catch

try {
  await deleteProvider(orgSlug, provider);
} catch (error) {
  if (isReauthError(error)) { startReauth(); return; }
  if (/\(404\)/.test(error.message)) { router.push(getLlmProvidersRoute(orgSlug)); return; }
  setDeleteError(error.message);
}

Prevention

When it happens

Trigger: DELETE returns e.g. 400 (provider still referenced by workers/policies or is a built-in managed provider), 401/403 (not an org owner/admin, session expired), 404 (provider already deleted), 5xx. Note the success path explicitly accepts 204, so 200-with-body and 4xx/5xx all throw.

Common situations: Deleting the last provider while active workers still reference it; a non-admin member attempting deletion; double-delete from a stale detail page; trying to remove a Den-managed/built-in provider that is read-only.

Related errors


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