mastra-ai/mastra · error

Default mode not found

Error message

Default mode not found: ${config.defaultModeId}

What it means

At construction, AgentController resolves a default mode: explicitly via config.defaultModeId, or implicitly via mode.default/metadata.default, falling back to modes[0]. If defaultModeId is set but no mode with that id exists, it throws 'Default mode not found' (the sibling message covers an entirely empty modes array).

Solutions

  1. Set defaultModeId to an existing mode id from the modes array
  2. Add a mode with the configured defaultModeId
  3. Make defaultModeId configuration-driven with a validation step against available mode ids before constructing

Example fix

// before
new AgentController({ modes: [{ id: 'chat' }], defaultModeId: 'agent' })
// after
new AgentController({ modes: [{ id: 'chat' }], defaultModeId: 'chat' })
Defensive patterns

Strategy: validation

Validate before calling

const modeIds = new Set(config.modes.map(m => m.id));
if (config.defaultModeId && !modeIds.has(config.defaultModeId)) {
  throw new Error(`defaultModeId "${config.defaultModeId}" is not a registered mode`);
}
if (config.modes.length === 0) throw new Error('AgentController requires at least one mode');

Try / catch

try {
  new AgentController(config);
} catch (e) {
  if ((e as Error).message.startsWith('Default mode not found')) {
    // correct defaultModeId from env/config to a registered mode id
  }
}

Prevention

When it happens

Trigger: new AgentController({ modes: [{id:'a'},{id:'b'}], defaultModeId: 'chat' }) where no mode has id 'chat' — from renamed modes, stale config, or env-driven default ids that don't match registered modes.

Common situations: Environment variable (e.g. DEFAULT_MODE) whose value was never registered as a mode; renaming a mode id without updating defaultModeId; copy-pasting controller configs across projects with different mode sets.

Related errors


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

Appendix: source

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

    validateModes(config.modes);

    this.id = config.id;
    this.config = config;
    this.#instructions = config.instructions;
    if (config.channels) {
      this.#channels = new AgentControllerChannels(config.channels);
      this.#channels.__setController(this);
    }
    // Gateway manager merges configured gateways with the router defaults
    // (custom takes precedence). Shared by listAvailableModels,
    // getCurrentModelAuthStatus, and the OM model resolver.
    this.#gatewayManager = new GatewayManager([...(config.gateways ?? []), ...defaultGateways]);

    const defaultMode = config.defaultModeId
      ? config.modes.find(mode => mode.id === config.defaultModeId)
      : (config.modes.find(mode => mode.default || mode.metadata?.default === true) ?? config.modes[0]);
    if (!defaultMode) {
      throw new Error(
        config.defaultModeId
          ? `Default mode not found: ${config.defaultModeId}`
          : 'AgentController requires at least one agent mode',
      );
    }

    this.#defaultMode = defaultMode;

    this.workspace = config.workspace;
    this.browser = config.browser;
  }

  /**
   * Subscribe to process-local notifications for newly materialized sessions.
   * Cached `createSession()` calls do not notify listeners again.
   *
   * Async listeners are fire-and-forget by default. Pass `blocking: true` to
   * make `createSession()` await the listener before resolving — for setup that

View on GitHub (pinned to 75dd419e61)