mastra-ai/mastra · error

@mastra/livekit: `configuration.endCall` has no effect with

Error message

@mastra/livekit: `configuration.endCall` has no effect with `generate` — the worker cannot observe tool calls from a custom reply generator. Detect the end-call tool inside your generator and call `runEndCall` directly instead.

What it means

`configuration.endCall` lets the built-in agent/workflow paths detect an end-call tool invocation and hang up. With a custom `generate` function, the worker never sees the model's tool calls, so endCall would silently do nothing; instead of failing at runtime, the library throws at construction time.

Source

Thrown at integrations/livekit/src/worker.ts:799

export function createLiveKitWorker(options: CreateLiveKitWorkerOptions) {
  if (options.generate && (options.agent || options.workflow)) {
    throw new Error(
      '@mastra/livekit: set exactly one reply generator — `generate`, `agent`, or `workflow` — not a combination.',
    );
  }
  if (options.agent && options.workflow) {
    throw new Error(
      '@mastra/livekit: set `agent` or `workflow`, not both — they are mutually exclusive reply generators.',
    );
  }
  if (options.workflow && !options.workflowInput) {
    throw new Error(
      '@mastra/livekit: `workflowInput` is required when `workflow` is set. Map the turn into the ' +
        'workflow inputData, e.g. workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }).',
    );
  }
  if (options.generate && options.configuration?.endCall) {
    throw new Error(
      '@mastra/livekit: `configuration.endCall` has no effect with `generate` — the worker cannot observe ' +
        'tool calls from a custom reply generator. Detect the end-call tool inside your generator and call ' +
        '`runEndCall` directly instead.',
    );
  }

  const wantsSileroVad = options.vad === undefined || options.vad === 'silero';

  // The turn detector's inference runners register at plugin-import time, and the agent
  // server only spawns its inference process for runners registered before it starts —
  // so begin the import now (worker definition happens at module scope, before
  // runLiveKitWorker boots the server, which awaits this).
  if (options.turnDetection === 'multilingual' || options.turnDetection === 'english') {
    requestEouMethod(EOU_METHODS[options.turnDetection]);
    queueWorkerSetup(
      import('@livekit/agents-plugin-livekit')
        .then(() => {
          // The plugin registers both language runners; keep only the requested ones so

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Remove `configuration.endCall` when using `generate`.
  2. Detect the end-call tool inside your `generate` function and invoke `runEndCall` directly from there.

Example fix

// before
createLiveKitWorker({ generate: myGenerate, configuration: { endCall: myEndCallConfig } });
// after
createLiveKitWorker({
  generate: async (ctx) => {
    const reply = await produceReply(ctx);
    if (reply.callsEndCallTool) await ctx.runEndCall();
    return reply;
  },
});
Defensive patterns

Strategy: validation

Validate before calling

if (options.generate && options.configuration?.endCall) throw new Error('configuration.endCall is unsupported with generate; call runEndCall from your generator instead');

Type guard

function endCallConfigCompatible(o: { generate?: unknown; configuration?: { endCall?: unknown } }): boolean {
  return !(o.generate != null && o.configuration?.endCall != null);
}

Try / catch

try {
  const worker = createLiveKitWorker(options);
} catch (e) {
  if ((e as Error).message.includes('endCall has no effect with generate')) {
    console.error('Remove configuration.endCall and call runEndCall inside your generator');
  } else throw e;
}

Prevention

When it happens

Trigger: createLiveKitWorker({ generate: myGenerator, configuration: { endCall: {...} } }) — the guard `options.generate && options.configuration?.endCall` fires.

Common situations: Enabling endCall on a custom generator config copied from an agent-based example; adding a `generate` callback later without removing the endCall configuration set earlier.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/cffb7a36b58b0353. Report an issue: GitHub.