different-ai/openwork · error · DenApiError

request_failed

request_failed

Error message

Request failed with ${raw.status}.

What it means

requestJson is the generic Den API response handler: when the HTTP response is not ok, it throws DenApiError with the status, an error code taken from the JSON body's `error` field (defaulting to "request_failed"), and a message "Request failed with <status>." unless the body supplies a message. This is the catch-all error for any non-2xx Den API call.

Source

Thrown at apps/app/src/app/lib/den.ts:2886

  try {
    json = text ? (JSON.parse(text) as T) : null;
  } catch {
    json = null;
  }
  return { ok: response.ok, status: response.status, json };
}

async function requestJson<T>(
  input: string | DenBaseUrls,
  path: string,
  options: DenRequestOptions = {},
): Promise<T> {
  const raw = await requestJsonRaw<T>(input, path, options);
  if (!raw.ok) {
    const payload = raw.json;
    const code = isRecord(payload) && typeof payload.error === "string" ? payload.error : "request_failed";
    const message = getErrorMessage(payload, `Request failed with ${raw.status}.`);
    throw new DenApiError(raw.status, code, message, isRecord(payload) ? payload.details : undefined);
  }
  return raw.json as T;
}

async function ensureActiveOrganization(
  baseUrls: DenBaseUrls,
  token: string | null,
  input: { organizationId?: string | null; organizationSlug?: string | null },
) {
  const organizationId = input.organizationId?.trim() ?? "";
  const organizationSlug = input.organizationSlug?.trim() ?? "";
  if (!token || (!organizationId && !organizationSlug)) {
    return;
  }

  await requestJson<unknown>(baseUrls, "/v1/me/active-organization", {
    method: "POST",
    token,

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Read err.status and err.code on the DenApiError to identify the actual failure
  2. For 401, re-authenticate (refresh the handoff/session token) before retrying
  3. Verify baseUrl/apiBaseUrl configuration points at the correct Den deployment
  4. Retry with backoff for transient 5xx statuses

Example fix

// before
const me = await client.getMe();
// after
try {
  const me = await client.getMe();
} catch (err) {
  if (err instanceof DenApiError && err.status === 401) await reauthenticate();
  else throw err;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!baseUrl || !/^https?:\/\//.test(baseUrl)) throw new Error("A valid Den baseUrl is required");
if (!authToken) throw new Error("Sign in before calling the Den API");

Type guard

const isDenApiError = (e: unknown): e is DenApiError =>
  e instanceof DenApiError && typeof e.status === "number" && typeof e.code === "string";

Try / catch

try {
  data = await callDenApi();
} catch (err) {
  if (isDenApiError(err)) {
    if (err.status === 401) await reauthenticate();
    else if (err.status >= 500) scheduleRetry();
    else showError(err.message, err.code);
  } else throw err;
}

Prevention

When it happens

Trigger: Any Den API request via requestJson that returns a non-ok status (401 unauthorized, 403 forbidden, 404 not found, 500 server error, etc.) without a more specific handler.

Common situations: Expired/missing auth token (401), wrong baseUrl or apiBaseUrl pointing at a wrong server, missing organization header, or the Den server being down (5xx).

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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