mastra-ai/mastra · error

Could not save the ${modeId} mode model

Error message

Could not save the ${modeId} mode model

What it means

switchCurrentModeModel writes the chosen modelId to the thread setting for the mode, then reads it back to verify the write actually persisted. If the read-back value differs from what was written, the persistence layer silently failed, and the command throws 'Could not save the <modeId> mode model' so the UI doesn't report success on a lost write.

Source

Thrown at mastracode/tui/src/tui/commands/models.ts:88

    } else {
      nextSettings.customModelPacks.push({
        name: customName,
        models: modeModels,
        createdAt: new Date().toISOString(),
      });
    }
    nextSettings.models.activeModelPackId = nextPackId;
    nextSettings.models.modeDefaults = modeModels;
  }

  let modeSettingSaved = false;
  let packSettingSaved = false;
  let globalSettingsWriteStarted = false;
  try {
    await ctx.state.session.thread.setSetting({ key: modeSettingKey, value: modelId });
    modeSettingSaved = true;
    const savedModeSetting = await ctx.state.session.thread.getSetting({ key: modeSettingKey });
    if (savedModeSetting !== modelId) throw new Error(`Could not save the ${modeId} mode model`);

    await ctx.state.session.thread.setSetting({ key: THREAD_ACTIVE_MODEL_PACK_ID_KEY, value: nextPackId });
    packSettingSaved = true;
    const savedPackSetting = await ctx.state.session.thread.getSetting({ key: THREAD_ACTIVE_MODEL_PACK_ID_KEY });
    if (savedPackSetting !== nextPackId) throw new Error('Could not save the active model pack');
    globalSettingsWriteStarted = true;
    saveSettings(nextSettings);
    await ctx.state.session.model.switch({ modelId, scope: 'global' });
  } catch (error) {
    if (globalSettingsWriteStarted) {
      try {
        saveSettings(settings);
      } catch {
        // Keep the original failure. The thread and active model still roll back below.
      }
    }

    const rollbacks: Array<Promise<unknown>> = [];

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Verify the storage/memory backend is writable and correctly wired to the session thread, then retry the model switch
  2. Retry the switch — transient storage failures resolve on a second attempt
  3. If it persists, inspect the storage adapter's set/getSetting implementation for lost writes or key mismatch (modeSettingKey)
Defensive patterns

Strategy: retry

Validate before calling

// Verify persistence works before switching models
const probeKey = '__write_probe__';
await ctx.state.session.thread.setSetting({ key: probeKey, value: 'ok' });
if ((await ctx.state.session.thread.getSetting({ key: probeKey })) !== 'ok') {
  throw new Error('Thread settings are not persisting — check the storage/memory backend.');
}

Try / catch

try {
  await switchCurrentModeModel(ctx, modeId, modelId, nextPackId);
} catch (e) {
  if (String(e.message).startsWith('Could not save the')) {
    console.error('Setting did not persist; verify the memory/storage backend is writable, then retry.');
  } else throw e;
}

Prevention

When it happens

Trigger: thread.setSetting succeeded without throwing but thread.getSetting returns a stale/different value — e.g. the memory/storage backend failed to persist, a concurrent write clobbered it, or the storage adapter ignores unknown setting keys.

Common situations: Storage backend misconfigured or read-only; session thread bound to a different memory instance than the one written; race with another writer to the same setting; custom memory adapter whose setSetting is a no-op.

Related errors


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