{"record":{"id":"7b1425e7fd97450b","repo":"thedotmack/claude-mem","slug":"transcript-watch-config-not-found-resolvedpath","errorCode":null,"errorMessage":"Transcript watch config not found: ${resolvedPath}","messagePattern":"Transcript watch config not found: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/transcripts/config.ts","lineNumber":68,"sourceCode":"      watches,\n    },\n    removed: config.watches.length - watches.length,\n  };\n}\n\nexport function expandHomePath(inputPath: string): string {\n  if (!inputPath) return inputPath;\n  // Shared expandTilde/expandHome leave `~user/...` alone (resolving another\n  // user's home is out of scope). The old inline version sliced one character\n  // off any leading tilde, so `~alice/transcripts` was rewritten to\n  // `<home>/alice/transcripts` and the watcher ingested nothing silently.\n  return expandTilde(inputPath);\n}\n\nexport function loadTranscriptWatchConfig(path = DEFAULT_CONFIG_PATH): TranscriptWatchConfig {\n  const resolvedPath = expandHomePath(path);\n  if (!existsSync(resolvedPath)) {\n    throw new Error(`Transcript watch config not found: ${resolvedPath}`);\n  }\n  const raw = readFileSync(resolvedPath, 'utf-8');\n  const parsed = JSON.parse(raw) as TranscriptWatchConfig;\n  if (!parsed.version || !parsed.watches) {\n    throw new Error(`Invalid transcript watch config: ${resolvedPath}`);\n  }\n  if (!parsed.stateFile) {\n    parsed.stateFile = DEFAULT_STATE_PATH;\n  }\n  return parsed;\n}\n\nexport function writeSampleConfig(path = DEFAULT_CONFIG_PATH): void {\n  const resolvedPath = expandHomePath(path);\n  const dir = dirname(resolvedPath);\n  if (!existsSync(dir)) {\n    mkdirSync(dir, { recursive: true });\n  }","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/transcripts/config.ts#L50-L86","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst cfg = loadTranscriptWatchConfig();\n// after\nconst cfgPath = existsSync(defaultPath) ? defaultPath : writeDefaultConfig(defaultPath);\nconst cfg = loadTranscriptWatchConfig(cfgPath);","handlingStrategy":"validation","validationCode":"import { existsSync } from 'fs';\nconst p = expandHomePath(path ?? DEFAULT_CONFIG_PATH);\nif (!existsSync(p)) createDefaultWatchConfig(p);","typeGuard":null,"tryCatchPattern":"try { const cfg = loadTranscriptWatchConfig(); } catch (e) { if (e.message.includes('config not found')) { bootstrapConfig(); } }","preventionTips":["Generate a default config on first run.","Echo the resolved path in errors and CLI help.","Avoid hardcoding absolute paths across machines/users."],"tags":["config","file","transcripts"],"backgroundTag":"config-file-not-found","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}