mastra-ai/mastra · error
@mastra/livekit: reply generation runs through the Mastra ag
Error message
@mastra/livekit: reply generation runs through the Mastra agent via llmNode; the placeholder LLM cannot be used for inference.
What it means
The placeholder LLM shipped inside MastraVoiceAgent implements chat() solely to satisfy the LiveKit Agent interface — it never performs inference. If code calls chat() directly (e.g. bypassing the agent's llmNode pipeline), the bridge throws this error to make it explicit that reply generation must flow through the Mastra agent via llmNode.
Source
Thrown at integrations/livekit/src/bridge.ts:415
* The session only runs its cascaded reply pipeline when an `llm` instance is present —
* `llmNode` replaces the inference step, but the gate checks `llm instanceof LLM`. This
* placeholder satisfies the gate; the Mastra agent/workflow does the actual generation.
*/
class MastraPlaceholderLLM extends llm.LLM {
label(): string {
return 'mastra.MastraVoiceAgent';
}
override get model(): string {
return 'mastra-agent';
}
override get provider(): string {
return 'mastra';
}
chat(): llm.LLMStream {
throw new Error(
'@mastra/livekit: reply generation runs through the Mastra agent via llmNode; the placeholder LLM cannot be used for inference.',
);
}
}
/**
* A LiveKit `voice.Agent` whose replies come from a Mastra agent or workflow.
*
* LiveKit keeps ownership of the audio loop (VAD, STT, turn detection, TTS, barge-in) and calls
* `llmNode` once per detected user turn; the node delegates to a {@link VoiceReplyGenerator}
* which streams text deltas back. On barge-in LiveKit cancels the returned stream, which aborts
* the in-flight generation.
*/
export class MastraVoiceAgent extends voice.Agent {
readonly mastraAgent?: MastraAgent;
readonly memory: MastraVoiceAgentMemory | false;
readonly requestContext?: RequestContext;
readonly streamOptions?: MastraStreamOptions;View on GitHub (pinned to 75dd419e61)
Solutions
- Do not call chat() on the agent's LLM; rely on llmNode which routes turns through the Mastra agent.
- Construct MastraVoiceAgent with a valid `agent` (Mastra agent instance) or `generate` function so llmNode has a real reply source.
- If you need manual reply generation, use the `generate` option instead of invoking the LLM directly.
- Remove or replace any custom pipeline code that calls the LLM's chat() method directly.
Example fix
// before const stream = await voiceAgent.llm.chat(chatCtx); // throws // after const stream = voiceAgent.llmNode(chatCtx, toolCtx); // routed through the Mastra agent
Defensive patterns
Strategy: try-catch
Try / catch
// never call voiceAgent.llm.chat() directly; if wrapping the pipeline:
try {
const stream = voiceAgent.llmNode(chatCtx, toolCtx);
} catch (err) {
if (err instanceof Error && err.message.includes('placeholder LLM cannot be used')) {
throw new Error('Misconfigured pipeline: route replies through llmNode with a real agent/generate');
}
throw err;
} Prevention
- Treat the agent's LLM as an internal placeholder; only use llmNode for inference.
- Always construct MastraVoiceAgent with a real `agent` or `generate` reply source.
- When porting vanilla LiveKit code, replace llm.chat(...) calls with the agent pipeline.
- Review custom pipeline components for direct LLM method invocation.
When it happens
Trigger: Calling chat() on a MastraVoiceAgent (or its placeholder LLM) directly, or configuring a LiveKit pipeline component that invokes the LLM's chat() instead of the agent's llmNode — e.g. custom turn-detection or manual session code driving the LLM itself.
Common situations: Porting plain LiveKit agent code that called this.llm.chat(...) manually; wiring the MastraVoiceAgent into a pipeline expecting a vanilla LLM; constructing MastraVoiceAgent without agent/generate and then trying to use its LLM.
Related errors
- @mastra/livekit: MastraVoiceAgent requires `agent` or `gener
- @mastra/livekit: MastraVoiceAgent requires `agent` or `gener
- @mastra/livekit: the agent requested tool approval or suspen
- connect({ id, name }): "name" is required when connecting wi
- MemoryThread.${methodName}() requires an agentId. Pass it vi
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/f9c687381d788712.
Report an issue: GitHub.