mastra-ai/mastra · error

@mastra/livekit: set LIVEKIT_API_KEY and LIVEKIT_API_SECRET

Error message

@mastra/livekit: set LIVEKIT_API_KEY and LIVEKIT_API_SECRET or pass apiKey/apiSecret to dispatchVoiceSession.

What it means

dispatchVoiceSession creates a LiveKit agent dispatch via AgentDispatchClient, which requires credentials. The function checks options.apiKey/options.apiSecret first, then falls back to LIVEKIT_API_KEY/LIVEKIT_API_SECRET env vars; it throws when both are missing so it never calls LiveKit with anonymous credentials.

Source

Thrown at integrations/livekit/src/dispatch.ts:36

}

function toHttpUrl(url: string): string {
  return url.replace(/^ws/, 'http');
}

/**
 * Programmatically dispatches a Mastra voice agent into a LiveKit room — for
 * server-initiated sessions such as outbound calls or joining an existing room.
 */
export async function dispatchVoiceSession(options: DispatchVoiceSessionOptions) {
  const serverUrl = options.serverUrl ?? process.env.LIVEKIT_URL;
  const apiKey = options.apiKey ?? process.env.LIVEKIT_API_KEY;
  const apiSecret = options.apiSecret ?? process.env.LIVEKIT_API_SECRET;
  if (!serverUrl) {
    throw new Error('@mastra/livekit: set LIVEKIT_URL or pass serverUrl to dispatchVoiceSession.');
  }
  if (!apiKey || !apiSecret) {
    throw new Error(
      '@mastra/livekit: set LIVEKIT_API_KEY and LIVEKIT_API_SECRET or pass apiKey/apiSecret to dispatchVoiceSession.',
    );
  }
  const client = new AgentDispatchClient(toHttpUrl(serverUrl), apiKey, apiSecret);
  return client.createDispatch(options.roomName, options.agentName ?? DEFAULT_LIVEKIT_AGENT_NAME, {
    metadata: serializeSessionMetadata(options.metadata ?? {}),
  });
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Set both LIVEKIT_API_KEY and LIVEKIT_API_SECRET in the environment running dispatchVoiceSession (from a LiveKit cloud API key or self-hosted key/secret pair).
  2. Alternatively pass apiKey and apiSecret explicitly in the options object to dispatchVoiceSession.
  3. Verify the secrets are actually loaded at runtime (e.g. dotenv config or platform secret injection) before dispatching.

Example fix

// before
await dispatchVoiceSession({ roomName: 'call-1', serverUrl });
// after
await dispatchVoiceSession({
  roomName: 'call-1',
  serverUrl,
  apiKey: process.env.LIVEKIT_API_KEY,
  apiSecret: process.env.LIVEKIT_API_SECRET,
});
Defensive patterns

Strategy: validation

Validate before calling

function assertLiveKitCredentials(opts = {}) {
  const key = opts.apiKey ?? process.env.LIVEKIT_API_KEY;
  const secret = opts.apiSecret ?? process.env.LIVEKIT_API_SECRET;
  if (!key || !secret) throw new Error('LiveKit dispatch needs apiKey/apiSecret or LIVEKIT_API_KEY/LIVEKIT_API_SECRET env vars');
  return { apiKey: key, apiSecret: secret };
}
assertLiveKitCredentials(); // run before dispatchVoiceSession

Try / catch

try {
  await dispatchVoiceSession(opts);
} catch (e) {
  if (e instanceof Error && e.message.includes('LIVEKIT_API_KEY')) {
    // fail fast: missing credentials, do not retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling dispatchVoiceSession without passing apiKey/apiSecret while neither LIVEKIT_API_KEY nor LIVEKIT_API_SECRET is set in the environment.

Common situations: Deploying to an environment where .env is not loaded (serverless, CI, containers); setting only LIVEKIT_URL; forgetting to propagate secrets to a worker process that dispatches sessions.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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