google-gemini/gemini-cli · error
LegacyAgentSession.send() only supports message sends for th
Error message
LegacyAgentSession.send() only supports message sends for the moment.
What it means
Thrown by the legacy session adapter's `send` when the incoming `AgentSend` payload has no `message` field. The adapter only knows how to translate full message sends into the legacy streaming protocol; other payload kinds (in-stream updates, elicitation responses, cancellations) are explicitly unsupported and rejected at the boundary.
Source
Thrown at packages/core/src/agent/legacy-agent-session.ts:111
this._scheduler = scheduler;
}
}
get events(): readonly AgentEvent[] {
return this._events;
}
subscribe(callback: (event: AgentEvent) => void): Unsubscribe {
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,View on GitHub (pinned to 5024443c72)
Solutions
- Only forward `{ message: ... }` payloads to `LegacyAgentSession.send`; route other payload kinds to a session implementation that supports them.
- Add a type guard that narrows the payload to the message variant before calling send.
- If you must use the legacy session, translate the unsupported payload into a new message send instead.
- Upgrade the session to a non-legacy implementation if you need full `AgentSend` coverage.
Example fix
// before
await legacySession.send({ update: { value: 1 } }); // throws
// after
function isMessageSend(p: AgentSend): p is { message: unknown } {
return 'message' in p;
}
if (isMessageSend(payload)) {
await legacySession.send(payload);
} else {
// route to a session that supports the payload kind
} Defensive patterns
Strategy: type-guard
Validate before calling
function isMessageSend(p: AgentSend): p is { message: unknown } {
return 'message' in p && p.message != null;
}
if (!isMessageSend(payload)) {
throw new Error('LegacyAgentSession only accepts message sends; got: ' + Object.keys(payload).join(','));
}
await legacySession.send(payload); Type guard
function isMessageSend(p: AgentSend): p is { message: unknown } {
return typeof p === 'object' && p !== null && 'message' in p && (p as { message: unknown }).message != null;
} Try / catch
try {
await legacySession.send(payload);
} catch (e) {
if (e instanceof Error && e.message.includes('only supports message sends')) {
// route the payload to a session that handles its kind
}
throw e;
} Prevention
- Filter AgentSend payloads by variant before dispatching to a legacy session.
- Prefer the non-legacy session implementation for code that needs the full send union.
- Document at the adapter boundary which payload kinds are supported.
When it happens
Trigger: Calling `legacySession.send(payload)` with a payload that is not a `{ message: ... }` shape — e.g. an `{ update: ... }`, `{ response: ... }`, or an empty object. The check is `'message' in payload ? payload.message : undefined`, then `if (!message) throw`.
Common situations: New code written against the newer `AgentSend` union being routed into a `LegacyAgentSession` (e.g. an adapter layer or a config that still selects the legacy implementation); a generic dispatcher that forwards any payload type without filtering; a payload that was built with optional chaining and silently dropped the `message` field.
Related errors
- Unknown eventId: ${options.eventId}
- Cannot resume from eventId ${options.eventId} before agent_s
- LegacyAgentSession.send() cannot be called while a stream is
- Invalid taskId: ${taskId}
- Security violation: Null byte detected in path.
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/b745a8fbb0293e24.
Report an issue: GitHub.