JuliusBrussee/caveman · error

bounded_response_unavailable

Error message

bounded_response_unavailable

What it means

After the size check, readRuntimePolicyResponseText needs to stream the response body via response.body.getReader(). If the body stream or getReader is unavailable (null body), it throws this error because a bounded read is impossible.

Solutions

  1. Ensure the runtime supports streaming fetch response bodies (modern Node 18+/browsers)
  2. Fix the request so the response is not opaque (avoid mode:'no-cors' for the policy endpoint)
  3. In tests, provide a Response with a real ReadableStream body
  4. Upgrade the fetch polyfill/undici to one supporting body streams

Example fix

// before
const res = await fetch(policyUrl, { mode: "no-cors" }); // opaque, body null
// after
const res = await fetch(policyUrl, { mode: "cors" });
Defensive patterns

Strategy: validation

Validate before calling

if (typeof Response !== "undefined") {
  const probe = new Response("x");
  if (!probe.body || typeof probe.body.getReader !== "function") {
    console.warn("runtime lacks streaming response bodies; runtime policy fetch will fail");
  }
}

Type guard

function hasReadableBody(res: Response): res is Response & { body: ReadableStream<Uint8Array> } {
  return !!res.body && typeof res.body.getReader === "function";
}

Try / catch

try {
  const text = await readRuntimePolicyResponseText(response);
} catch (e) {
  if (e.message === "bounded_response_unavailable") useNonStreamingFetchFallback();
  else throw e;
}

Prevention

When it happens

Trigger: Fetch Response whose body is null or lacks getReader() — e.g. in runtimes without streaming response support, opaque no-cors responses, or mocked Response objects without a body.

Common situations: Running in an older runtime/polyfilled environment where fetch responses have no readable body; unit tests passing a fake Response with body: null; opaque cross-origin responses (type: 'opaque').

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/c1b7604c0f206d90. Report an issue: GitHub.

Appendix: source

Thrown at packages/sdk/typescript/src/index.ts:883

}

// ─── Runtime policy client ────────────────────────────────────────────────────

/** Schema version this client accepts; anything else is rejected (fail closed). */
const RUNTIME_POLICY_SCHEMA_VERSION = "caveman.runtime-policy.v1";

/** Runtime-policy envelopes are KB-sized; stop a hostile body after 1 MiB. */
const RUNTIME_POLICY_MAX_RESPONSE_BYTES = 1024 * 1024;

async function readRuntimePolicyResponseText(response: Response): Promise<string> {
  const contentLength = response.headers?.get?.("content-length");
  if (typeof contentLength === "string" && /^[0-9]+$/.test(contentLength) && Number(contentLength) > RUNTIME_POLICY_MAX_RESPONSE_BYTES) {
    await Promise.resolve(response.body?.cancel?.()).catch(() => undefined);
    throw new Error("oversized_response");
  }

  const reader = response.body?.getReader?.();
  if (!reader) throw new Error("bounded_response_unavailable");
  const chunks: Uint8Array[] = [];
  let total = 0;
  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      if (!(value instanceof Uint8Array)) throw new Error("runtime policy response stream returned invalid bytes");
      total += value.byteLength;
      if (total > RUNTIME_POLICY_MAX_RESPONSE_BYTES) {
        await Promise.resolve(reader.cancel()).catch(() => undefined);
        throw new Error("oversized_response");
      }
      chunks.push(value);
    }
  } finally {
    try {
      reader.releaseLock();
    } catch {

View on GitHub (pinned to 3ee70a1026)