mastra-ai/mastra · error

@mastra/livekit: no workflow specified. Set `workflow` on cr

Error message

@mastra/livekit: no workflow specified. Set `workflow` on createLiveKitWorker.

What it means

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.

Source

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

    return options.mastra.getAgentById(ref);
  } catch {
    return options.mastra.getAgent(ref);
  }
}

// Returns the workflow boxed in an object: `Workflow` is thenable (it has a `.then()` builder
// method), so a bare `Promise<Workflow>` return — or awaiting a `Workflow`-typed value — trips
// TS's thenable checks and, at runtime, `await workflow` would call the builder's `.then`.
async function resolveWorkflow(
  options: CreateLiveKitWorkerOptions,
  args: ResolveMastraAgentArgs,
): Promise<{ workflow: Workflow }> {
  const resolver = options.workflow;
  // The function form resolves to an id string (safe to await); a Workflow instance is only
  // accepted as a direct value, never awaited.
  const ref: string | Workflow = typeof resolver === 'function' ? await resolver(args) : (resolver ?? '');
  if (!ref) {
    throw new Error('@mastra/livekit: no workflow specified. Set `workflow` on createLiveKitWorker.');
  }
  if (typeof ref !== 'string') return { workflow: ref };
  // getWorkflowById matches by workflow id and falls back to the registration key.
  return { workflow: options.mastra.getWorkflowById(ref as never) as Workflow };
}

function resolveMemory(
  options: CreateLiveKitWorkerOptions,
  mastraAgent: MastraAgent | undefined,
  args: ResolveMastraAgentArgs,
  roomName: string,
): MastraVoiceAgentMemory | false {
  if (options.memory === false) return false;
  if (typeof options.memory === 'function') return options.memory({ ...args, roomName });
  // With an agent, default to memory only when the agent has its own. With a workflow (no
  // agent), default the thread/resource mapping so the workflow input can use it.
  if (mastraAgent && !mastraAgent.hasOwnMemory()) return false;
  const thread = args.metadata.threadId ?? roomName;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Set `workflow` on createLiveKitWorker to a Workflow instance or a workflow id string.
  2. If using the function form, ensure it resolves to a non-empty workflow id string.
  3. Verify the id passed matches a workflow registered on the Mastra instance (getWorkflowById matches by id or registration key).

Example fix

// before
const options = { mastra }; // workflow missing
createLiveKitWorker(options);
// after
createLiveKitWorker({ mastra, workflow: mastra.getWorkflow('voiceFlow') });
// or
createLiveKitWorker({ mastra, workflow: 'voiceFlow' });
Defensive patterns

Strategy: validation

Validate before calling

function assertWorkflowConfigured(workerOptions) {
  const w = typeof workerOptions.workflow === 'function' ? undefined : workerOptions.workflow;
  if (!w) throw new Error('createLiveKitWorker requires a `workflow` (Workflow instance or non-empty id string)');
}
assertWorkflowConfigured(opts); // before createLiveKitWorker(opts)

Try / catch

try {
  createLiveKitWorker(options);
} catch (e) {
  if (e instanceof Error && e.message.includes('no workflow specified')) {
    console.error('workflow option was:', typeof options.workflow, options.workflow);
  }
  throw e;
}

Prevention

When it happens

Trigger: createLiveKitWorker called without a `workflow` option, or with a resolver function that returns undefined/empty string; passing an empty string as the workflow id.

Common situations: 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).

Related errors


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