thedotmack/claude-mem · error

No mode loaded. Call loadMode() first.

Error message

No mode loaded. Call loadMode() first.

What it means

getActiveMode() returns the currently merged ModeConfig, but the manager is a stateful object that requires loadMode() to have been called first. If activeMode is still unset, it throws this error. It is a lifecycle/initialization-order guard, not a data problem.

Solutions

  1. Call `await modeManager.loadMode(...)` before any getActiveMode()/getObservationTypes() call.
  2. Check why the earlier loadMode() failed (fix that error first) — active mode stays unset.
  3. Guard call sites: only query the manager after initialization completes (e.g. an `initialized` flag/promise).
  4. If modes are optional in your context, wrap access in try-catch and use a default config.

Example fix

// before
const mm = new ModeManager(dirs);
const types = mm.getObservationTypes(); // throws
// after
const mm = new ModeManager(dirs);
await mm.loadMode('code');
const types = mm.getObservationTypes();
Defensive patterns

Strategy: try-catch

Validate before calling

let managerReady = false;
async function initManager(m, modeId) { await m.loadMode(modeId); managerReady = true; }
if (!managerReady) throw new Error('ModeManager not initialized');

Type guard

const isReady = (m: ModeManager & { activeMode?: unknown }): boolean => (m as any).activeMode != null;

Try / catch

try { const types = manager.getObservationTypes(); } catch (e) { if (e.message.includes('No mode loaded')) { await manager.loadMode('code'); return manager.getObservationTypes(); } throw e; }

Prevention

When it happens

Trigger: Calling getActiveMode() (directly or via getObservationTypes()) on a fresh ModeManager instance before any successful loadMode() call, or after loadMode() threw and left no active mode.

Common situations: Constructor-time code reading observation types before mode load completes; async initialization race where getObservationTypes() runs before await loadMode() resolves; swallowing the loadMode error earlier and continuing.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/433abc4ad9256003. Report an issue: GitHub.

Appendix: source

Thrown at src/services/domain/ModeManager.ts:178

    }

    const mergedMode = this.deepMerge(parentMode, overrideConfig);
    this.activeMode = mergedMode;
    this.activeModeId = modeId;

    logger.debug('SYSTEM', `Loaded mode with inheritance: ${mergedMode.name} (${modeId} = ${parentId} + ${overrideId})`, undefined, {
      parent: parentId,
      override: overrideId,
      types: mergedMode.observation_types.map(t => t.id),
      concepts: mergedMode.observation_concepts.map(c => c.id)
    });

    return mergedMode;
  }

  getActiveMode(): ModeConfig {
    if (!this.activeMode) {
      throw new Error('No mode loaded. Call loadMode() first.');
    }
    return this.activeMode;
  }

  getActiveModeId(): string {
    if (!this.activeModeId) {
      throw new Error('No mode loaded. Call loadMode() first.');
    }
    return this.activeModeId;
  }

  getObservationTypes(): ObservationType[] {
    return this.getActiveMode().observation_types;
  }

  getTypeIcon(typeId: string): string {
    const type = this.getObservationTypes().find(t => t.id === typeId);
    return type?.emoji || '📝';

View on GitHub (pinned to d8bc9755e7)