thedotmack/claude-mem · error

Mode file not found: ${modeId}.json (searched: ${this.modeDi

Error message

Mode file not found: ${modeId}.json (searched: ${this.modeDirs.join(', ')})

What it means

Thrown by ModeManager.loadModeFile() after the mode id passes the regex but no <modeId>.json file exists in any of the searched mode directories (CLAUDE_MEM_MODES_DIR, dataDir/modes, packageRoot/modes, packageRoot/../plugin/modes). The message lists every directory searched so the user can see where it looked.

Source

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

      } else {
        result[key] = overrideValue as T[Extract<keyof T, string>];
      }
    }

    return result;
  }

  private loadModeFile(modeId: string): ModeConfig {
    if (!MODE_ID_PATTERN.test(modeId)) {
      throw new Error(`Invalid mode ID: ${modeId}`);
    }

    const modePath = this.modeDirs
      .map(modesDir => join(modesDir, `${modeId}.json`))
      .find(candidate => existsSync(candidate));

    if (!modePath) {
      throw new Error(`Mode file not found: ${modeId}.json (searched: ${this.modeDirs.join(', ')})`);
    }

    const jsonContent = readFileSync(modePath, 'utf-8');
    return JSON.parse(jsonContent) as ModeConfig;
  }

  loadMode(modeId: string): ModeConfig {
    const inheritance = this.parseInheritance(modeId);

    if (!inheritance.hasParent) {
      try {
        const mode = this.loadModeFile(modeId);
        this.activeMode = mode;
        this.activeModeId = modeId;
        logger.debug('SYSTEM', `Loaded mode: ${mode.name} (${modeId})`, undefined, {
          types: mode.observation_types.map(t => t.id),
          concepts: mode.observation_concepts.map(c => c.id)
        });

View on GitHub (pinned to d768ba3643)

Solutions

  1. Create the missing <modeId>.json in one of the listed directories (dataDir/modes for user modes is durable across upgrades).
  2. Fix CLAUDE_MEM_MODES_DIR to point at the directory that actually contains your modes.
  3. If the mode was removed intentionally, switch to a mode that exists (the fallback chain tries 'code' next).

Example fix

// before — modes/research.json does not exist anywhere in modeDirs
manager.loadMode('research');
// throws 'Mode file not found: research.json (searched: /a/modes, /b/modes, ...)'

// after — create the file
// <dataDir>/modes/research.json
{ "name": "Research", "observation_types": [...], "observation_concepts": [...] }
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'fs';
const candidate = modeDirs.map(d => join(d, `${modeId}.json`)).find(existsSync);
if (!candidate) {
  throw new Error(`No mode file for ${modeId}; searched: ${modeDirs.join(', ')}`);
}

Type guard

function modeFileExists(modeId: string, modeDirs: string[]): boolean {
  return modeDirs.some(d => existsSync(join(d, `${modeId}.json`)));
}

Prevention

When it happens

Trigger: Calling loadMode('my-custom') when modes/my-custom.json does not exist in any modeDir; mode file was deleted during a plugin upgrade; CLAUDE_MEM_MODES_DIR points at the wrong folder.

Common situations: User-created mode lived in dataDir/modes which got wiped on reinstall; mode id is correct but file extension is wrong; modes directory never got copied into the package; dev path differs from installed path so plugin/modes is empty.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/6ef5497d2c3df4b2. Report an issue: GitHub.