{"record":{"id":"ddc3d7bd1804b7fb","repo":"mastra-ai/mastra","slug":"mastra-livekit-no-workflow-specified-set-workf","errorCode":null,"errorMessage":"@mastra/livekit: no workflow specified. Set `workflow` on createLiveKitWorker.","messagePattern":"@mastra/livekit: no workflow specified\\. Set `workflow` on createLiveKitWorker\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integrations/livekit/src/worker.ts","lineNumber":273,"sourceCode":"    return options.mastra.getAgentById(ref);\n  } catch {\n    return options.mastra.getAgent(ref);\n  }\n}\n\n// Returns the workflow boxed in an object: `Workflow` is thenable (it has a `.then()` builder\n// method), so a bare `Promise<Workflow>` return — or awaiting a `Workflow`-typed value — trips\n// TS's thenable checks and, at runtime, `await workflow` would call the builder's `.then`.\nasync function resolveWorkflow(\n  options: CreateLiveKitWorkerOptions,\n  args: ResolveMastraAgentArgs,\n): Promise<{ workflow: Workflow }> {\n  const resolver = options.workflow;\n  // The function form resolves to an id string (safe to await); a Workflow instance is only\n  // accepted as a direct value, never awaited.\n  const ref: string | Workflow = typeof resolver === 'function' ? await resolver(args) : (resolver ?? '');\n  if (!ref) {\n    throw new Error('@mastra/livekit: no workflow specified. Set `workflow` on createLiveKitWorker.');\n  }\n  if (typeof ref !== 'string') return { workflow: ref };\n  // getWorkflowById matches by workflow id and falls back to the registration key.\n  return { workflow: options.mastra.getWorkflowById(ref as never) as Workflow };\n}\n\nfunction resolveMemory(\n  options: CreateLiveKitWorkerOptions,\n  mastraAgent: MastraAgent | undefined,\n  args: ResolveMastraAgentArgs,\n  roomName: string,\n): MastraVoiceAgentMemory | false {\n  if (options.memory === false) return false;\n  if (typeof options.memory === 'function') return options.memory({ ...args, roomName });\n  // With an agent, default to memory only when the agent has its own. With a workflow (no\n  // agent), default the thread/resource mapping so the workflow input can use it.\n  if (mastraAgent && !mastraAgent.hasOwnMemory()) return false;\n  const thread = args.metadata.threadId ?? roomName;","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/integrations/livekit/src/worker.ts#L255-L291","documentation":"resolveWorkflow resolves the workflow the voice worker will run: options.workflow (value or function), with Workflow instances accepted only as direct values (never awaited). It throws when no workflow value or id can be resolved — an empty/undefined resolver result — because the worker has nothing to execute per call.","triggerScenarios":"createLiveKitWorker called without a `workflow` option, or with a resolver function that returns undefined/empty string; passing an empty string as the workflow id.","commonSituations":"Omitting the workflow option entirely; a dynamic workflow resolver that fails to find an id and returns undefined; registering workflows under a different key than the id passed to the resolver (which would instead fail later in getWorkflowById).","solutions":["Set `workflow` on createLiveKitWorker to a Workflow instance or a workflow id string.","If using the function form, ensure it resolves to a non-empty workflow id string.","Verify the id passed matches a workflow registered on the Mastra instance (getWorkflowById matches by id or registration key)."],"exampleFix":"// before\nconst options = { mastra }; // workflow missing\ncreateLiveKitWorker(options);\n// after\ncreateLiveKitWorker({ mastra, workflow: mastra.getWorkflow('voiceFlow') });\n// or\ncreateLiveKitWorker({ mastra, workflow: 'voiceFlow' });","handlingStrategy":"validation","validationCode":"function assertWorkflowConfigured(workerOptions) {\n  const w = typeof workerOptions.workflow === 'function' ? undefined : workerOptions.workflow;\n  if (!w) throw new Error('createLiveKitWorker requires a `workflow` (Workflow instance or non-empty id string)');\n}\nassertWorkflowConfigured(opts); // before createLiveKitWorker(opts)","typeGuard":null,"tryCatchPattern":"try {\n  createLiveKitWorker(options);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('no workflow specified')) {\n    console.error('workflow option was:', typeof options.workflow, options.workflow);\n  }\n  throw e;\n}","preventionTips":["Always pass `workflow` explicitly to createLiveKitWorker — never rely on dynamic resolution alone.","Make workflow resolvers throw on lookup failure instead of returning undefined.","Keep workflow ids in a shared constants module to avoid empty-string ids.","Smoke-test worker startup in CI so missing options fail before deployment."],"tags":["configuration","workflows","livekit"],"backgroundTag":"missing-required-configuration","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}