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
- Create the missing <modeId>.json in one of the listed directories (dataDir/modes for user modes is durable across upgrades).
- Fix CLAUDE_MEM_MODES_DIR to point at the directory that actually contains your modes.
- 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
- Place user modes in dataDir/modes so they survive plugin upgrades.
- Confirm CLAUDE_MEM_MODES_DIR points at the real modes folder before relying on it.
- After upgrades, verify the bundled modes/ directory (especially code.json) shipped correctly.
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
- Invalid mode inheritance: ${modeId}. Only one level of inher
- Invalid mode ID: ${modeId}
- Critical: code.json mode file missing
- Corrupt JSON in ${GEMINI_SETTINGS_PATH}, refusing to overwri
- Corrupt hooks.json at ${WINDSURF_HOOKS_JSON_PATH}, refusing
AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12).
Data as JSON: /api/errors/6ef5497d2c3df4b2.
Report an issue: GitHub.