different-ai/openwork · error · Error

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

Error message

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

What it means

Thrown by saveProvider in llm-provider-editor-screen.tsx when the POST/PUT that creates or updates an LLM provider (20s timeout) returns non-ok. The thrown error comes from getRequestError (den-flow.ts:527): a ReauthRequiredError for 403 {error:'reauth'}, otherwise the server's `error` message or the fallback "Failed to save provider (<status>).".

Source

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

                body.apiKey = apiKey.trim();
            }

            const path = provider
                ? `/v1/llm-providers/${encodeURIComponent(provider.id)}`
                : `/v1/llm-providers`;
            const method = provider ? "PATCH" : "POST";

            const { response, payload } = await requestJson(
                path,
                {
                    method,
                    body: JSON.stringify(body),
                },
                20000,
            );

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

            const nextProvider =
                payload &&
                typeof payload === "object" &&
                payload &&
                "llmProvider" in payload &&
                payload.llmProvider &&
                typeof payload.llmProvider === "object"
                    ? (payload.llmProvider as { id?: unknown })
                    : null;
            const nextProviderId =
                typeof nextProvider?.id === "string"
                    ? nextProvider.id
                    : (provider?.id ?? null);
            if (!nextProviderId) {
                throw new Error(
                    "The provider was saved, but no provider id was returned.",

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Validate inputs client-side before submit: trim the API key, check base URL format, and ensure the model ids exist (the editor already builds `body` — sanitize before JSON.stringify).
  2. On 409, pick a unique provider name.
  3. On 401/403, run reauth (isReauthRequiredError) or confirm the user has admin rights.
  4. On 404, reload the provider list — the record was deleted by someone else.

Example fix

// before
if (!response.ok) {
  throw getRequestError(payload, response, `Failed to save provider (${response.status}).`);
}
// after
const apiKey = input.apiKey.trim();
if (apiKey.length === 0) throw new Error("API key is required.");
if (!response.ok) {
  throw getRequestError(payload, response, `Failed to save provider (${response.status}).`);
}
Defensive patterns

Strategy: validation

Validate before calling

// before saveProvider
const apiKey = form.apiKey.trim();
if (apiKey.length === 0) throw new Error("API key is required.");
try { new URL(form.baseUrl); } catch { throw new Error("Base URL must be a valid URL."); }
if (form.name.trim().length === 0) throw new Error("Name is required.");
const duplicate = providers.some((p) => p.name === form.name.trim() && p.id !== form.id);
if (duplicate) throw new Error("A provider with this name already exists.");

Type guard

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

Try / catch

try {
  await saveProvider(orgSlug, payload);
} catch (error) {
  if (isReauthError(error)) { startReauth(); return; }
  if (/\(409\)/.test(error.message)) { setFieldError("name", "Name already in use."); return; }
  setFormError(error.message);
}

Prevention

When it happens

Trigger: Saving provider settings (endpoint, API key, model list) returns non-ok: 400/422 (invalid base URL, malformed key, unsupported model id, bad JSON body), 401/403 (insufficient org role, expired session), 404 (provider was deleted while editing), 409 (duplicate provider name), 5xx, or exceeds the 20000ms timeout.

Common situations: Pasting an API key with whitespace/newlines or wrong provider prefix; using an internal base URL the Den server cannot reach; renaming to a name that already exists; the provider being removed by another admin mid-edit; server-side validation of model ids failing after a models list update.

Related errors


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