can1357/oh-my-pi · error · AnthropicStreamEnvelopeError

Anthropic SDK request did not expose a stream response

Error message

Anthropic SDK request did not expose a stream response

What it means

This AnthropicStreamEnvelopeError is thrown when the SDK request promise returned by the Anthropic client does not implement the withResponse() contract the library relies on. The library needs the raw HTTP response (headers, request id) alongside the decoded event stream, so a request without this surface cannot be observed.

Source

Thrown at packages/ai/src/providers/anthropic.ts:1519

	events: AsyncIterable<AnthropicStreamEvent>;
	response: Response;
	requestId: string | null;
	recordsRawSseEvents: boolean;
}> {
	if (hasAnthropicRawResponseRequest(request)) {
		const response = await request.asResponse();
		return {
			events: iterateAnthropicEvents(response, signal, onSseEvent),
			response,
			requestId: response.headers.get("request-id"),
			recordsRawSseEvents: true,
		};
	}
	if (hasAnthropicStreamWithResponseRequest(request)) {
		const { data, response, request_id } = await request.withResponse();
		return { events: data, response, requestId: request_id, recordsRawSseEvents: false };
	}
	throw new AIError.AnthropicStreamEnvelopeError("Anthropic SDK request did not expose a stream response");
}

async function* observeDecodedAnthropicSdkEvents(
	events: AsyncIterable<AnthropicStreamEvent>,
	observer: (event: RawSseEvent) => void,
): AsyncGenerator<AnthropicStreamEvent> {
	for await (const event of events) {
		const data = JSON.stringify(event);
		// Reconstructed from decoded SDK event; not literal wire bytes.
		notifyRawSseEvent(observer, { event: event.type, data, raw: [`event: ${event.type}`, `data: ${data}`] });
		yield event;
	}
}

const PROVIDER_MAX_RETRIES = 10;

/**
 * Flat delay between attempts when Copilot 400s a model its own `/models`

View on GitHub (pinned to 9690622007)

Solutions

  1. Upgrade or align @anthropic-ai/sdk to the version this library expects so stream requests expose withResponse().
  2. If mocking in tests, implement withResponse() returning { data, response, request_id }.
  3. Verify the raw client instance (not a partially wrapped object) is passed to the streaming path.
  4. Check hasAnthropicStreamWithResponseRequest expectations against the SDK's actual API surface in node_modules.

Example fix

// before
messages: { create: async () => eventStream } // no withResponse

// after
messages: {
  create: async () => ({
    [Symbol.asyncIterator]: eventStream[Symbol.asyncIterator].bind(eventStream),
    withResponse: async () => ({ data: eventStream, response: rawResponse, request_id: "req_1" }),
  }),
}
Defensive patterns

Strategy: type-guard

Validate before calling

function isStreamRequestWithResponse(req: unknown): req is { withResponse(): Promise<{ data: AsyncIterable<unknown>; response: Response; request_id?: string }> } {
  return typeof req === "object" && req !== null && "withResponse" in req && typeof (req as { withResponse?: unknown }).withResponse === "function";
}
// check before handing the SDK request to the streaming path

Type guard

const request = client.messages.create(params, options);
if (typeof (request as { withResponse?: unknown }).withResponse !== "function") {
  throw new Error("Anthropic SDK does not expose withResponse(); upgrade @anthropic-ai/sdk.");
}

Try / catch

try {
  const { events, response } = await request.withResponse();
  return { events, response };
} catch (err) {
  if (err instanceof AIError.AnthropicStreamEnvelopeError && /did not expose a stream response/.test(err.message)) {
    // fall back to a manual fetch SSE request to the messages endpoint
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling the streaming path with an Anthropic SDK client whose messages.create result lacks the withResponse() method (hasAnthropicStreamWithResponseRequest returns false) — typically a different/incompatible SDK version, a mock, or a non-SDK object passed where the client's request promise is expected.

Common situations: Pinning an older or forked @anthropic-ai/sdk that changed the return type; mocking client.messages.create with a plain AsyncIterable in tests; wrapping the client in a proxy that drops methods; using a gateway SDK that mimics but does not match the official API.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/13a94ef7482f6d39. Report an issue: GitHub.