{"record":{"id":"cffb7a36b58b0353","repo":"mastra-ai/mastra","slug":"mastra-livekit-configuration-endcall-has-no-ef","errorCode":null,"errorMessage":"@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.","messagePattern":"@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\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integrations/livekit/src/worker.ts","lineNumber":799,"sourceCode":"export function createLiveKitWorker(options: CreateLiveKitWorkerOptions) {\n  if (options.generate && (options.agent || options.workflow)) {\n    throw new Error(\n      '@mastra/livekit: set exactly one reply generator — `generate`, `agent`, or `workflow` — not a combination.',\n    );\n  }\n  if (options.agent && options.workflow) {\n    throw new Error(\n      '@mastra/livekit: set `agent` or `workflow`, not both — they are mutually exclusive reply generators.',\n    );\n  }\n  if (options.workflow && !options.workflowInput) {\n    throw new Error(\n      '@mastra/livekit: `workflowInput` is required when `workflow` is set. Map the turn into the ' +\n        'workflow inputData, e.g. workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }).',\n    );\n  }\n  if (options.generate && options.configuration?.endCall) {\n    throw new Error(\n      '@mastra/livekit: `configuration.endCall` has no effect with `generate` — the worker cannot observe ' +\n        'tool calls from a custom reply generator. Detect the end-call tool inside your generator and call ' +\n        '`runEndCall` directly instead.',\n    );\n  }\n\n  const wantsSileroVad = options.vad === undefined || options.vad === 'silero';\n\n  // The turn detector's inference runners register at plugin-import time, and the agent\n  // server only spawns its inference process for runners registered before it starts —\n  // so begin the import now (worker definition happens at module scope, before\n  // runLiveKitWorker boots the server, which awaits this).\n  if (options.turnDetection === 'multilingual' || options.turnDetection === 'english') {\n    requestEouMethod(EOU_METHODS[options.turnDetection]);\n    queueWorkerSetup(\n      import('@livekit/agents-plugin-livekit')\n        .then(() => {\n          // The plugin registers both language runners; keep only the requested ones so","sourceCodeStart":781,"sourceCodeEnd":817,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/integrations/livekit/src/worker.ts#L781-L817","documentation":"`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.","triggerScenarios":"createLiveKitWorker({ generate: myGenerator, configuration: { endCall: {...} } }) — the guard `options.generate && options.configuration?.endCall` fires.","commonSituations":"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.","solutions":["Remove `configuration.endCall` when using `generate`.","Detect the end-call tool inside your `generate` function and invoke `runEndCall` directly from there."],"exampleFix":"// before\ncreateLiveKitWorker({ generate: myGenerate, configuration: { endCall: myEndCallConfig } });\n// after\ncreateLiveKitWorker({\n  generate: async (ctx) => {\n    const reply = await produceReply(ctx);\n    if (reply.callsEndCallTool) await ctx.runEndCall();\n    return reply;\n  },\n});","handlingStrategy":"validation","validationCode":"if (options.generate && options.configuration?.endCall) throw new Error('configuration.endCall is unsupported with generate; call runEndCall from your generator instead');","typeGuard":"function endCallConfigCompatible(o: { generate?: unknown; configuration?: { endCall?: unknown } }): boolean {\n  return !(o.generate != null && o.configuration?.endCall != null);\n}","tryCatchPattern":"try {\n  const worker = createLiveKitWorker(options);\n} catch (e) {\n  if ((e as Error).message.includes('endCall has no effect with generate')) {\n    console.error('Remove configuration.endCall and call runEndCall inside your generator');\n  } else throw e;\n}","preventionTips":["Only configure configuration.endCall for agent/workflow workers","Encapsulate end-call detection in your generate function via runEndCall","Centralize worker option building in one typed factory to keep incompatible combos unrepresentable"],"tags":["configuration","livekit","validation"],"backgroundTag":"incompatible-options","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}