google-gemini/gemini-cli · error
LegacyAgentSession.send() cannot be called while a stream is
Error message
LegacyAgentSession.send() cannot be called while a stream is active.
What it means
Thrown by `LegacyAgentSession.send` when a second send arrives while `_activeStreamId` is still set — i.e. a stream is mid-flight. The legacy adapter has no correlation semantics for interleaved in-stream sends (updates, elicitation responses), so it rejects all concurrent sends defensively until the active stream completes and clears the flag.
Source
Thrown at packages/core/src/agent/legacy-agent-session.ts:120
this._subscribers.add(callback);
return () => {
this._subscribers.delete(callback);
};
}
async send(payload: AgentSend): Promise<{ streamId: string }> {
const message = 'message' in payload ? payload.message : undefined;
if (!message) {
throw new Error(
'LegacyAgentSession.send() only supports message sends for the moment.',
);
}
if (this._activeStreamId) {
// TODO: Interactive may eventually allow selected in-stream sends such as
// updates or elicitation responses. Keep rejecting all concurrent sends
// here until we define those correlation semantics.
throw new Error(
'LegacyAgentSession.send() cannot be called while a stream is active.',
);
}
this._beginNewStream();
const streamId = this._translationState.streamId;
const parts = contentPartsToGeminiParts(message.content);
const userMessage = this._makeUserMessageEvent(
message.content,
message.displayContent,
payload._meta,
);
this._emit([userMessage]);
this._scheduleRunLoop(parts, message.displayContent);
return { streamId };View on GitHub (pinned to 5024443c72)
Solutions
- Await the full resolution of the active stream (consume until `agent_end`) before issuing the next `send`.
- Serialize sends through a queue so only one stream is active at a time.
- Disable/ignore the submit affordance in the UI while a stream is active.
- If you genuinely need concurrent or in-stream sends, switch to a non-legacy session implementation that defines those semantics.
Example fix
// before
legacySession.send(msg1); // not awaited
legacySession.send(msg2); // throws — stream active
// after
for await (const _ of legacySession.stream(msg1)) { /* drain */ }
await legacySession.send(msg2); // previous stream finished Defensive patterns
Strategy: validation
Validate before calling
// serialize sends through a queue
let sendChain: Promise<unknown> = Promise.resolve();
function queuedSend(session: LegacyAgentSession, payload: AgentSend) {
const next = sendChain.then(() => session.send(payload));
sendChain = next.catch(() => {}); // never break the chain
return next;
} Try / catch
try {
await legacySession.send(payload);
} catch (e) {
if (e instanceof Error && e.message.includes('while a stream is active')) {
// enqueue the send for after the active stream ends
return;
}
throw e;
} Prevention
- Serialize sends per session with a promise chain or queue.
- In UIs, disable submit while a stream is active.
- Drain streams to completion (until agent_end) before issuing the next send.
- If concurrency is required, upgrade to a session that defines correlation semantics.
When it happens
Trigger: Two `send` calls overlap in time: the first triggered `_beginNewStream()` and set `_activeStreamId`, and a second `send` was issued before the first stream's `agent_end` resolved. Also occurs when a caller tries to push an update into a running stream.
Common situations: A UI 'submit' button without debounce allowing double-submits; an orchestration loop that fires follow-up messages without awaiting the prior stream; an event-driven pipeline that reacts to partial output by sending again; mixing the legacy session with code that assumed concurrent send support.
Related errors
- Cannot resume from eventId ${options.eventId} before agent_s
- LegacyAgentSession.send() only supports message sends for th
- Exiting due to an error processing the @ command.
- Operation cancelled.
- Reached max session turns for this session. Increase the num
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/298b906d3676af58.
Report an issue: GitHub.