can1357/oh-my-pi · warning · AuthBrokerStreamUnsupportedError

AuthBrokerStreamUnsupportedError

Error message

AuthBrokerStreamUnsupportedError

What it means

The auth broker stream endpoint returned HTTP 404, meaning this broker deployment does not support the SSE snapshot-stream endpoint. The client drains the tiny body (to reuse the socket) and throws AuthBrokerStreamUnsupportedError so callers can fall back to polling fetchSnapshot instead of treating it as a hard failure.

Source

Thrown at packages/ai/src/auth-broker/client.ts:213

	 * to long-polling for the remainder of its lifetime.
	 */
	async *openSnapshotStream(opts: { signal?: AbortSignal } = {}): AsyncGenerator<SnapshotStreamEvent> {
		const url = `${this.#baseUrl}/v1/snapshot/stream`;
		const headers: Record<string, string> = {
			Accept: "text/event-stream",
			Authorization: `Bearer ${this.#token}`,
			[AUTH_BROKER_CAPABILITIES_HEADER]: AUTH_BROKER_CAPABILITY_CODEX_METER_BLOCK_SCOPES,
		};
		if (opts.signal?.aborted) {
			throw new AuthBrokerError("Auth broker request aborted", { cause: opts.signal.reason });
		}
		// No timeout: this connection is intentionally long-lived. Caller's signal
		// is the only cancel path.
		const response = await this.#fetch(url, { method: "GET", headers, signal: opts.signal });
		if (response.status === 404) {
			// Drain the body so the socket can be reused; tiny payload.
			await response.text().catch(() => {});
			throw new AuthBrokerStreamUnsupportedError();
		}
		if (!response.ok) {
			const text = await response.text().catch(() => "");
			throw new AuthBrokerError(`Auth broker stream failed: ${response.status} ${response.statusText}`, {
				status: response.status,
				body: text,
			});
		}
		if (!response.body) {
			throw new AuthBrokerError("Auth broker stream response had no body", { status: response.status });
		}
		const contentType = response.headers.get("content-type")?.toLowerCase();
		if (contentType?.split(";", 1)[0].trim() !== "text/event-stream") {
			await response.body.cancel().catch(() => {});
			throw new AuthBrokerError("Auth broker stream returned non-SSE response", {
				status: response.status,
				body: contentType ?? "",
			});

View on GitHub (pinned to 9690622007)

Solutions

  1. Catch AuthBrokerStreamUnsupportedError and fall back to polling fetchSnapshot (the intended contract)
  2. Upgrade the auth broker deployment to a version with the stream endpoint
  3. Verify the broker base URL routes to the current broker service, not a legacy gateway
  4. Check reverse-proxy/load-balancer routing rules for the stream path

Example fix

// before: assuming stream always exists
const stream = await client.openSnapshotStream({ signal })
// after: fallback to polling
try {
  const stream = await client.openSnapshotStream({ signal })
} catch (e) {
  if (e instanceof AuthBrokerStreamUnsupportedError) startPolling(client)
  else throw e
}
Defensive patterns

Strategy: fallback

Validate before calling

// feature-detect: probe the stream endpoint once and remember support
let streamSupported: boolean | null = null;
if (streamSupported === false) startPolling(client); else openStreamWithFallback();

Type guard

function isStreamUnsupported(err: unknown): err is AuthBrokerStreamUnsupportedError {
  return err instanceof AuthBrokerStreamUnsupportedError;
}

Try / catch

try {
  const stream = await client.openSnapshotStream({ signal });
  consume(stream);
} catch (err) {
  if (err instanceof AuthBrokerStreamUnsupportedError) {
    startPolling(client); // graceful degradation to fetchSnapshot polling
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: openSnapshotStream receives a 404 from the broker's stream URL — an older broker without the streaming endpoint, a reverse proxy stripping the route, or a wrong base URL that routes to a server lacking the endpoint.

Common situations: Broker and client version mismatch after a client upgrade; load balancer in front of brokers with mixed versions; AUTH_BROKER_URL pointing at a legacy gateway.

Related errors


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