{"record":{"id":"8d23d7534fb7730e","repo":"thedotmack/claude-mem","slug":"invalid-transcript-watch-config-resolvedpath","errorCode":null,"errorMessage":"Invalid transcript watch config: ${resolvedPath}","messagePattern":"Invalid transcript watch config: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/services/transcripts/config.ts","lineNumber":72,"sourceCode":"}\n\nexport function expandHomePath(inputPath: string): string {\n  if (!inputPath) return inputPath;\n  if (inputPath.startsWith('~')) {\n    return join(homedir(), inputPath.slice(1));\n  }\n  return 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  }\n  writeFileSync(resolvedPath, JSON.stringify(SAMPLE_CONFIG, null, 2));\n}\n","sourceCodeStart":54,"sourceCodeEnd":88,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/transcripts/config.ts#L54-L88","documentation":"Thrown by loadTranscriptWatchConfig when the config file exists and parses as JSON but is missing the required `version` or `watches` field. The loader requires both keys to consider the config valid; their absence means the file is structurally incomplete.","triggerScenarios":"loadTranscriptWatchConfig: existsSync passes, readFileSync + JSON.parse succeeds, but `parsed.version` or `parsed.watches` is falsy. Note JSON.parse throwing a SyntaxError would surface as a separate unhandled parse error before this check.","commonSituations":"Hand-edited config with a typo (e.g. `watch` instead of `watches`), a partial/old config schema from a prior version that lacked `watches`, an empty `{}` file, or a file overwritten by another tool. The message names the resolved path for inspection.","solutions":["Open the resolved path and add the missing top-level fields: `version` (number, currently 1) and `watches` (array, possibly empty).","If unsure of the shape, back up the bad file and regenerate via writeSampleConfig() then re-apply your custom watches.","Validate the JSON with a linter to rule out a silent parse into the wrong structure.","Upgrade-stale configs: migrate old fields into the current version/watches schema."],"exampleFix":"// before: { \"stateFile\": \"/...\" }  // missing version + watches -> throws\n// after:  { \"version\": 1, \"watches\": [], \"stateFile\": \"/...\" }","handlingStrategy":"validation","validationCode":"function isValidConfig(c: unknown): c is TranscriptWatchConfig {\n  return typeof c === 'object' && c !== null\n    && typeof (c as any).version === 'number'\n    && Array.isArray((c as any).watches);\n}\n// usage:\nconst parsed = JSON.parse(readFileSync(resolved, 'utf-8'));\nif (!isValidConfig(parsed)) throw new Error('config missing version or watches');","typeGuard":"function isTranscriptWatchConfig(c: unknown): c is TranscriptWatchConfig {\n  if (typeof c !== 'object' || c === null) return false;\n  const o = c as Record<string, unknown>;\n  return typeof o.version === 'number' && Array.isArray(o.watches);\n}","tryCatchPattern":"try { config = loadTranscriptWatchConfig(path); }\ncatch (e) {\n  if (e instanceof Error && e.message.startsWith('Invalid transcript watch config')) {\n    // back up and regenerate\n    writeSampleConfig(path); config = loadTranscriptWatchConfig(path); return;\n  }\n  throw e;\n}","preventionTips":["Validate version + watches presence right after JSON.parse before trusting the shape.","Keep a known-good sample (writeSampleConfig) to fall back to on structural failure.","Add a JSON-schema check in CI for committed transcript configs."],"tags":["transcripts","config","validation","schema"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}