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
- Ensure the runtime supports streaming fetch response bodies (modern Node 18+/browsers)
- Fix the request so the response is not opaque (avoid mode:'no-cors' for the policy endpoint)
- In tests, provide a Response with a real ReadableStream body
- 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
- Run on runtimes with streaming fetch support (Node 18+, modern browsers)
- Avoid mode:'no-cors'/opaque responses for the policy endpoint
- Use real ReadableStream bodies in test doubles
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
- AbortError
- binary download failed
- This operation was aborted
- awscreds: read response
- awscreds: read sts response
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)