can1357/oh-my-pi · error · AnthropicStreamEnvelopeError
Anthropic cache refresh request did not expose a raw respons
Error message
Anthropic cache refresh request did not expose a raw response
What it means
This AnthropicStreamEnvelopeError is thrown during cache refresh when the request promise returned by the Anthropic client lacks the asResponse() method, so the library cannot access the raw HTTP response. The cache-refresh flow must read the raw JSON body and notify listeners with response metadata, which requires the raw response surface.
Source
Thrown at packages/ai/src/providers/anthropic.ts:2051
rawRequestDump = {
provider: model.provider,
api: output.api,
model: model.id,
method: "POST",
url: `${baseUrl}/v1/messages${isOAuthToken ? "?beta=true" : ""}`,
body: refreshParams,
};
const { requestSignal } = activeAbortTracker;
const requestOptions = {
...createSdkStreamRequestOptions(requestSignal, requestTimeoutMs),
maxRetries: 0,
};
const request: unknown =
isOAuthToken && client.beta
? client.beta.messages.create(refreshParams, requestOptions)
: client.messages.create(refreshParams, requestOptions);
if (!hasAnthropicRawResponseRequest(request)) {
throw new AIError.AnthropicStreamEnvelopeError(
"Anthropic cache refresh request did not expose a raw response",
);
}
const response = await request.asResponse();
await notifyProviderResponse(options, response, model, response.headers.get("request-id"));
const body: unknown = await response.json();
if (!isRecord(body)) {
throw new AIError.AnthropicStreamEnvelopeError("Anthropic cache refresh returned a malformed response");
}
const wireUsage = parseAnthropicWireUsage(body.usage);
if (!wireUsage) {
throw new AIError.AnthropicStreamEnvelopeError("Anthropic cache refresh response omitted usage");
}
if (typeof body.id === "string") output.responseId = body.id;
output.usage.input = wireUsage.input_tokens ?? 0;
output.usage.output = wireUsage.output_tokens ?? 0;
output.usage.cacheRead = wireUsage.cache_read_input_tokens ?? 0;
output.usage.cacheWrite = wireUsage.cache_creation_input_tokens ?? 0;View on GitHub (pinned to 9690622007)
Solutions
- Use a supported @anthropic-ai/sdk version where messages.create returns a request exposing asResponse().
- Update test mocks to implement asResponse() returning a Response.
- Ensure the client isn't wrapped by a proxy that strips methods before reaching the refresh path.
- Confirm the OAuth vs non-OAuth branch: both beta and non-beta clients must expose the raw response.
Example fix
// before
create: async (params) => paramsJson // no asResponse
// after
create: async (params) => ({
json: paramsJson,
asResponse: async () => new Response(JSON.stringify(paramsJson), { headers: { "request-id": "req_1" } }),
}) Defensive patterns
Strategy: type-guard
Validate before calling
const request = client.messages.create(refreshParams, requestOptions);
if (typeof (request as { asResponse?: unknown }).asResponse !== "function") {
throw new Error("Cache refresh requires an SDK request exposing asResponse(); check SDK version.");
} Type guard
function hasRawResponseRequest(req: unknown): req is { asResponse(): Promise<Response> } {
return typeof req === "object" && req !== null && "asResponse" in req && typeof (req as { asResponse?: unknown }).asResponse === "function";
} Try / catch
try {
const response = await request.asResponse();
const body = await response.json();
return parseRefreshUsage(body);
} catch (err) {
if (err instanceof AIError.AnthropicStreamEnvelopeError && /did not expose a raw response/.test(err.message)) {
// degrade: skip cache-usage refresh for this cycle instead of failing the turn
} else {
throw err;
}
} Prevention
- Keep the raw client instance unwrapped through to the refresh call site.
- Include asResponse() in any client test double used with cache-refresh paths.
- Align SDK versions across packages that share the Anthropic client.
- Cover both the OAuth (beta) and standard client branches in integration tests.
When it happens
Trigger: client.messages.create (or client.beta.messages.create) returns an object failing hasAnthropicRawResponseRequest — e.g. an incompatible SDK version, a mock without asResponse(), or a wrapped/proxied client during a non-streaming cache-refresh call.
Common situations: Older/forked @anthropic-ai/sdk without asResponse on non-streaming creates; test doubles that only implement the happy-path shape; middleware replacing the client; swapping to a compatible-but-different client library.
Related errors
- Anthropic SDK request did not expose a stream response
- Anthropic cache refresh returned a malformed response
- Anthropic cache refresh response omitted usage
- No active model on agent
- Request was aborted.
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/ae8f5abe14186e3e.
Report an issue: GitHub.