can1357/oh-my-pi · error

Live transport is not connected

Error message

Live transport is not connected

What it means

send() serializes a live client message onto the call's sideband WebSocket, but only when the transport state is "connected". If the transport has never connected, or was closed/failed, it refuses to enqueue the write and throws synchronously at the state check.

Source

Thrown at packages/coding-agent/src/live/transport.ts:374

	#handlePeerFailure(message: string): void {
		this.#reportFailure(message);
	}

	#reportFailure(message: string): void {
		if ((this.#state !== "connecting" && this.#state !== "connected") || this.#unexpectedFailureReported) {
			return;
		}
		this.#unexpectedFailureReported = true;
		try {
			this.#options.callbacks.onEvent({ type: "error", message });
		} catch {}
	}

	/** Serialize one Frameless Bidi control message onto the call's sideband WebSocket. */
	send(message: LiveClientMessage): Promise<void> {
		const operation = this.#sendTail.then(() => {
			if (this.#state !== "connected") throw new Error("Live transport is not connected");
			const sideband = this.#sideband;
			if (!sideband || sideband.readyState !== WebSocket.OPEN) {
				throw new Error("Codex live sideband is not connected");
			}
			sideband.send(JSON.stringify(message));
		});
		this.#sendTail = operation.catch(() => {});
		return operation;
	}

	/** Queue 16 kHz mono Float32 PCM for native Opus transmission. */
	pushAudio(samples: Float32Array): void {
		if (this.#state !== "connected" || this.#muted || samples.length === 0) return;
		this.#peer?.pushAudio(samples);
	}

	/** Enable or disable the native audio source and discard partial input when muted. */
	async setMuted(muted: boolean): Promise<void> {

View on GitHub (pinned to 9690622007)

Solutions

  1. Check transport state (or a connected flag) before calling send.
  2. Await connect() completion before sending any messages.
  3. Reconnect the transport, then resend queued messages.
  4. Guard sends inside try/catch and requeue on "not connected" errors.

Example fix

// before
transport.send({ type: "input", text });
// after
if (transport.state === "connected") {
  await transport.send({ type: "input", text });
} else {
  pendingQueue.push({ type: "input", text });
}
Defensive patterns

Strategy: try-catch

Validate before calling

function canSend(t: { state: string }): boolean {
  return t.state === "connected";
}
// gate sends:
if (canSend(transport)) await transport.send(msg); else outbox.push(msg);

Type guard

const isConnected = (t: { state: string }): t is { state: "connected" } => t.state === "connected";

Try / catch

try {
  await transport.send(msg);
} catch (e) {
  if (e.message === "Live transport is not connected") {
    outbox.push(msg);
    await reconnectTransport();
  } else throw e;
}

Prevention

When it happens

Trigger: Calling transport.send() before connect() resolves, after close(), or after the underlying call dropped and state transitioned away from "connected" (e.g. during reconnect).

Common situations: Sending a control message from an event handler racing a disconnect, forgetting to await connect(), or app code holding a stale transport reference after the live session ended.

Related errors


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