thedotmack/claude-mem · error
Transcript watch config not found
Error message
Transcript watch config not found: ${resolvedPath} What it means
loadTranscriptWatchConfig expands the given path (tilde/home expansion) and requires the file to exist before reading. If no file is present at the resolved path, it throws with the resolved path so the user knows exactly where the config was looked up. The transcript watch feature cannot run without its watches config.
Solutions
- Create the transcript watch config JSON at the resolved path shown in the error message.
- Or pass an explicit path: loadTranscriptWatchConfig('/path/to/watches.json').
- Verify $HOME / user context matches where the config was installed.
- Fix typos in the CLI --config path argument.
Example fix
// before const cfg = loadTranscriptWatchConfig(); // after const cfgPath = existsSync(defaultPath) ? defaultPath : writeDefaultConfig(defaultPath); const cfg = loadTranscriptWatchConfig(cfgPath);
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'fs';
const p = expandHomePath(path ?? DEFAULT_CONFIG_PATH);
if (!existsSync(p)) createDefaultWatchConfig(p); Try / catch
try { const cfg = loadTranscriptWatchConfig(); } catch (e) { if (e.message.includes('config not found')) { bootstrapConfig(); } } Prevention
- Generate a default config on first run.
- Echo the resolved path in errors and CLI help.
- Avoid hardcoding absolute paths across machines/users.
When it happens
Trigger: Calling loadTranscriptWatchConfig(path?) — directly or via runTranscriptCommand — when the resolved path (default DEFAULT_CONFIG_PATH, e.g. a transcript-watches.json under ~/.claude-mem) does not exist.
Common situations: Fresh install where the watch config was never created; typo in the path passed via CLI; config file moved or deleted; running as a different user whose $HOME lacks the file.
Understand the failure class
Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.
Related errors
- Missing schema for watch
- Skipped Codex transcript watch because native Codex hooks…
- ActiveServerQueueManager requires…
- CLAUDE_MEM_QUEUE_ENGINE is not "bullmq"
- CLAUDE_MEM_TELEGRAM_WRAPUP_ROUTES must be a JSON object
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/7b1425e7fd97450b.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/transcripts/config.ts:68
watches,
},
removed: config.watches.length - watches.length,
};
}
export function expandHomePath(inputPath: string): string {
if (!inputPath) return inputPath;
// Shared expandTilde/expandHome leave `~user/...` alone (resolving another
// user's home is out of scope). The old inline version sliced one character
// off any leading tilde, so `~alice/transcripts` was rewritten to
// `<home>/alice/transcripts` and the watcher ingested nothing silently.
return expandTilde(inputPath);
}
export function loadTranscriptWatchConfig(path = DEFAULT_CONFIG_PATH): TranscriptWatchConfig {
const resolvedPath = expandHomePath(path);
if (!existsSync(resolvedPath)) {
throw new Error(`Transcript watch config not found: ${resolvedPath}`);
}
const raw = readFileSync(resolvedPath, 'utf-8');
const parsed = JSON.parse(raw) as TranscriptWatchConfig;
if (!parsed.version || !parsed.watches) {
throw new Error(`Invalid transcript watch config: ${resolvedPath}`);
}
if (!parsed.stateFile) {
parsed.stateFile = DEFAULT_STATE_PATH;
}
return parsed;
}
export function writeSampleConfig(path = DEFAULT_CONFIG_PATH): void {
const resolvedPath = expandHomePath(path);
const dir = dirname(resolvedPath);
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true });
}View on GitHub (pinned to d8bc9755e7)