unslothai/unsloth · error

Request failed (${status})

Error message

Request failed (${status})

What it means

Fallback branch of parseErrorText in providers-api.ts: the error response body parsed but contained neither a formattable FastAPI detail nor a string message field (or failed to parse), so only the numeric status is reported. It backs all provider CRUD error paths (parseJsonOrThrow plus explicit deleteProviderConfig/cancelCodexOAuthFlow throws).

Source

Thrown at studio/frontend/src/features/chat/api/providers-api.ts:82

  message: string;
  models_count?: number | null;
}

function parseErrorText(status: number, body: unknown): string {
  if (body && typeof body === "object") {
    const detail = (body as { detail?: unknown }).detail;
    const formatted = formatFastApiDetail(detail);
    if (formatted) return formatted;
    const message = (body as { message?: unknown }).message;
    if (typeof message === "string" && message) return message;
  }
  return `Request failed (${status})`;
}

async function parseJsonOrThrow<T>(response: Response): Promise<T> {
  const body = await response.json().catch(() => null);
  if (!response.ok) {
    throw new Error(parseErrorText(response.status, body));
  }
  return body as T;
}

export function isProviderKeyRotationError(error: unknown): boolean {
  if (!(error instanceof Error)) return false;
  const normalized = error.message.toLowerCase();
  return (
    normalized.includes("public key may have changed") ||
    normalized.includes("server key may have changed")
  );
}

let cachedPublicKeyPem: string | null = null;
let cachedForgeKey: forge.pki.rsa.PublicKey | null = null;

export function clearProviderPublicKeyCache(): void {
  cachedPublicKeyPem = null;

View on GitHub (pinned to 203007d190)

Solutions

  1. Map the status: 401/403 auth, 502/503 backend-down, 5xx server bug — then check the corresponding logs.
  2. Ensure the backend's global exception handler returns JSON {detail} so clients get real messages.
  3. Retry after backend recovery for 5xx.
Defensive patterns

Strategy: try-catch

Try / catch

try { await updateProviderConfig(id, payload); }
catch (e) {
  if (isProviderKeyRotationError(e)) { forceRefreshProviderKey(); return retry(); }
  if (/Request failed \((401|403)\)/.test(e.message)) promptReauth();
  else showError(e.message);
}

Prevention

When it happens

Trigger: Any /api/providers/* request failing with an empty or non-JSON error body — gateway 502 with an HTML page, a bare 500, or 401 from an auth layer that sends no JSON.

Common situations: Studio backend down behind a proxy; auth middleware short-circuiting; server error handlers not wrapping unexpected exceptions in the {detail} envelope.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/b04096eb7611a2d2. Report an issue: GitHub.