mastra-ai/mastra · error

Duplicate mode id "${mode.id}" found when creating the Agent

Error message

Duplicate mode id "${mode.id}" found when creating the AgentController

What it means

validateModes runs when constructing an AgentController and enforces that every agent mode has a unique id. If two modes share the same id, it throws immediately at construction time so duplicate mode registrations fail fast rather than causing ambiguous mode resolution at runtime.

Source

Thrown at packages/core/src/agent-controller/agent-controller.ts:66

  ToolCategory,
} from './types';

/**
 * Registry key for the session map. JSON-encodes the (resourceId, scope) pair
 * so the key is collision-proof for arbitrary strings: a scoped session can
 * never collide with an unscoped one or with a different resource/scope split
 * (e.g. `("a\0b", "c")` vs `("a", "b\0c")`).
 */
function sessionRegistryKey(resourceId: string, scope?: string): string {
  return JSON.stringify([resourceId, scope ?? null]);
}

function validateModes(modes: AgentControllerMode[]): void {
  const modeIds = new Set<string>();

  for (const mode of modes) {
    if (modeIds.has(mode.id)) {
      throw new Error(`Duplicate mode id "${mode.id}" found when creating the AgentController`);
    }

    modeIds.add(mode.id);

    const modeRecord = mode as unknown as { id: string; tools?: unknown; additionalTools?: unknown };
    if (modeRecord.tools && modeRecord.additionalTools) {
      throw new Error(
        `Mode "${modeRecord.id}" cannot set both "tools" and "additionalTools" - choose replace OR augment`,
      );
    }
  }

  for (const mode of modes) {
    if (mode.transitionsTo === mode.id) {
      throw new Error(`Mode "${mode.id}" transitionsTo cannot reference itself`);
    }
    if (mode.transitionsTo && !modeIds.has(mode.transitionsTo)) {
      throw new Error(`Mode "${mode.id}" transitionsTo references unknown mode "${mode.transitionsTo}"`);

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Give each mode in the modes array a unique id before constructing the controller
  2. Deduplicate merged mode lists (e.g. by id) prior to construction
  3. Check for double registration of the same mode from config files or plugins

Example fix

// before
modes: [{ id: 'chat', ... }, { id: 'chat', ... }]
// after
modes: [{ id: 'chat', ... }, { id: 'review', ... }]
Defensive patterns

Strategy: validation

Validate before calling

function assertUniqueModeIds(modes: { id: string }[]): void {
  const ids = modes.map(m => m.id);
  if (new Set(ids).size !== ids.length) throw new Error('Duplicate mode ids: ' + ids.join(','));
}
assertUniqueModeIds(config.modes);

Try / catch

try {
  const controller = new AgentController(config);
} catch (e) {
  if ((e as Error).message.startsWith('Duplicate mode id')) {
    // dedupe config.modes by id and reconstruct
  }
}

Prevention

When it happens

Trigger: Passing a modes array to new AgentController(config) containing two AgentControllerMode objects with identical id values, e.g. copy-pasted mode definitions or merging mode lists from two sources without deduplication.

Common situations: Copy-pasting a mode config and forgetting to change its id; programmatically merging default and user modes that both define an 'edit' or 'ask' id; feature flags that append the same mode twice.

Related errors


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