redis/node-redis · error · Error

HTTP ${response.status} - Unable to parse response as JSON

Error message

HTTP ${response.status} - Unable to parse response as JSON

What it means

Thrown by #request when response.ok is true (2xx) but response.json() throws — the server returned a 2xx with a body that is not valid JSON. The status code is included so the caller can see the successful HTTP status that preceded the parse failure.

Source

Thrown at packages/test-utils/lib/fault-injector/fault-injector-client.ts:234

        headers,
        body: payload,
        signal: controller.signal
      });

      if (!response.ok) {
        try {
          const text = await response.text();
          throw new Error(`HTTP ${response.status} - ${text}`);
        } catch {
          throw new Error(`HTTP ${response.status}`);
        }
      }

      try {
        const result = (await response.json()) as T;
        return result;
      } catch {
        throw new Error(
          `HTTP ${response.status} - Unable to parse response as JSON`
        );
      }
    } finally {
      globalThis.clearTimeout(timeoutId);
    }
  }

  /**
   * Deletes a database.
   * @param clusterIndex The index of the cluster
   * @param bdbId The database ID (optional if dbConfig is set)
   * @throws {Error} When the HTTP request fails or response cannot be parsed as JSON
   */
  public async deleteDatabase(
    bdbId?: number | string,
    clusterIndex: number = 0
  ) {

View on GitHub (pinned to 90fd0652bc)

Solutions

  1. Reproduce the request with curl -i to inspect Content-Type and the raw body
  2. Confirm baseUrl points at the fault-injector API, not a generic web server
  3. Verify the fault-injector service version matches the client's expected contract

Example fix

# before
Error: HTTP 200 - Unable to parse response as JSON

# after — inspect the actual response
curl -i $FI_BASE_URL/action
# if it returns HTML, fix baseUrl to the real API host
Defensive patterns

Strategy: validation

Validate before calling

async function safeRequest<T>(fi: FaultInjectorClient, method: string, path: string): Promise<T> {
  try {
    return await (fi as any).#request<T>(method, path);
  } catch (e) {
    if (e instanceof Error && /Unable to parse response as JSON/.test(e.message)) {
      throw new Error(`${e.message} — check that baseUrl points at the JSON API`);
    }
    throw e;
  }
}

Try / catch

try {
  const res = await fi.listActions();
} catch (e) {
  if (e instanceof Error && /Unable to parse response as JSON/.test(e.message)) {
  }
  throw e;
}

Prevention

When it happens

Trigger: The fault-injector endpoint returns 200 with an empty body, an HTML error page, or plain text instead of JSON; a proxy/gateway in front rewrites the response; the endpoint changed its content type.

Common situations: Reverse proxy returning an HTML 200 error page; misconfigured baseUrl pointing at a non-API server; service version mismatch where an endpoint now returns text; truncated response on a flaky connection.

Understand the failure class

Related errors


AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11). Data as JSON: /api/errors/2ce6e894a87a648d. Report an issue: GitHub.