{"record":{"id":"b745a8fbb0293e24","repo":"google-gemini/gemini-cli","slug":"legacyagentsession-send-only-supports-message-se","errorCode":null,"errorMessage":"LegacyAgentSession.send() only supports message sends for the moment.","messagePattern":"LegacyAgentSession\\.send\\(\\) only supports message sends for the moment\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agent/legacy-agent-session.ts","lineNumber":111,"sourceCode":"      this._scheduler = scheduler;\n    }\n  }\n\n  get events(): readonly AgentEvent[] {\n    return this._events;\n  }\n\n  subscribe(callback: (event: AgentEvent) => void): Unsubscribe {\n    this._subscribers.add(callback);\n    return () => {\n      this._subscribers.delete(callback);\n    };\n  }\n\n  async send(payload: AgentSend): Promise<{ streamId: string }> {\n    const message = 'message' in payload ? payload.message : undefined;\n    if (!message) {\n      throw new Error(\n        'LegacyAgentSession.send() only supports message sends for the moment.',\n      );\n    }\n\n    if (this._activeStreamId) {\n      // TODO: Interactive may eventually allow selected in-stream sends such as\n      // updates or elicitation responses. Keep rejecting all concurrent sends\n      // here until we define those correlation semantics.\n      throw new Error(\n        'LegacyAgentSession.send() cannot be called while a stream is active.',\n      );\n    }\n\n    this._beginNewStream();\n    const streamId = this._translationState.streamId;\n    const parts = contentPartsToGeminiParts(message.content);\n    const userMessage = this._makeUserMessageEvent(\n      message.content,","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/agent/legacy-agent-session.ts#L93-L129","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","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."],"exampleFix":"// before\nawait legacySession.send({ update: { value: 1 } }); // throws\n\n// after\nfunction isMessageSend(p: AgentSend): p is { message: unknown } {\n  return 'message' in p;\n}\nif (isMessageSend(payload)) {\n  await legacySession.send(payload);\n} else {\n  // route to a session that supports the payload kind\n}","handlingStrategy":"type-guard","validationCode":"function isMessageSend(p: AgentSend): p is { message: unknown } {\n  return 'message' in p && p.message != null;\n}\n\nif (!isMessageSend(payload)) {\n  throw new Error('LegacyAgentSession only accepts message sends; got: ' + Object.keys(payload).join(','));\n}\nawait legacySession.send(payload);","typeGuard":"function isMessageSend(p: AgentSend): p is { message: unknown } {\n  return typeof p === 'object' && p !== null && 'message' in p && (p as { message: unknown }).message != null;\n}","tryCatchPattern":"try {\n  await legacySession.send(payload);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('only supports message sends')) {\n    // route the payload to a session that handles its kind\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["agent-session","legacy","type-narrowing","validation"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}