mastra-ai/mastra · error

Mode not found: ${modeId}

Error message

Mode not found: ${modeId}

What it means

ModeState.switch() validates the requested modeId against the host's mode catalog before changing state. If the catalog resolver returns no definition for that id, the switch is rejected up front so no partial switch (version bump, model change events) occurs.

Source

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

  /** Set the currently-selected mode id (on default resolution or hydration). */
  set({ modeId }: { modeId: string }): void {
    this.#id = modeId;
  }

  /**
   * Switch to a different mode.
   *
   * Emits `mode_changed`, then runs the version-guarded sequence: remember the
   * outgoing mode's model, persist the new mode, then resolve and apply the
   * incoming mode's model — emitting `model_changed` once applied. A newer
   * switch starting mid-flight supersedes this one, which then bails before
   * emitting `model_changed`.
   */
  async switch({ modeId }: { modeId: string }): Promise<void> {
    const mode = this.#resolveMode?.(modeId) ?? null;
    if (!mode) {
      throw new Error(`Mode not found: ${modeId}`);
    }

    const previousModeId = this.#id;
    const previousModelId = this.#model.get();
    const version = ++this.#switchVersion;
    this.#id = modeId;

    // Emit the mode change immediately so UIs can update without waiting for
    // the storage round-trips below.
    this.#bus.emit({ type: 'mode_changed', modeId, previousModeId });

    // Remember the outgoing mode's model before moving on.
    if (previousModelId) {
      await this.#model.saveForMode({ modeId: previousModeId, modelId: previousModelId });
    }
    if (this.#switchVersion !== version) return;

    await this.#store()?.set(MODE_ID_KEY, modeId);

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Validate the id against the catalog before switching (resolve or list modes first).
  2. Update the caller to a current mode id from the catalog's default.
  3. Register the missing mode in the catalog, or migrate stale saved mode ids on load.

Example fix

// before
await session.mode.switch({ modeId: 'build' }); // throws if 'build' no longer exists
// after
const available = getCatalogModeIds();
const id = available.includes('build') ? 'build' : defaultModeId;
await session.mode.switch({ modeId: id });
Defensive patterns

Strategy: validation

Validate before calling

const valid = !!resolveMode(modeId);
if (!valid) throw new Error(`Unknown mode: ${modeId}; available: ${listModeIds().join(', ')}`);

Try / catch

try {
  await session.mode.switch({ modeId });
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Mode not found: ')) {
    await session.mode.switch({ modeId: defaultModeId });
  } else throw e;
}

Prevention

When it happens

Trigger: Calling switch({ modeId }) with a typo'd id, an id from another project's catalog, or a mode that was removed/renamed; programmatic switching based on stale persisted preferences.

Common situations: Custom modes registered conditionally (env-dependent) so the id is absent at runtime; renaming a built-in mode in an upgrade; user config referencing removed modes.

Related errors


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