{"record":{"id":"c25b4ee6c80e2f12","repo":"thedotmack/claude-mem","slug":"missing-schema-for-watch","errorCode":null,"errorMessage":"Missing schema for watch","messagePattern":"Missing schema for watch","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/services/transcripts/watcher.ts","lineNumber":116,"sourceCode":"      await this.setupWatch(watch);\n    }\n  }\n\n  stop(): void {\n    for (const tailer of this.tailers.values()) {\n      tailer.close();\n    }\n    this.tailers.clear();\n    for (const watcher of this.rootWatchers) {\n      watcher.close();\n    }\n    this.rootWatchers = [];\n  }\n\n  private async setupWatch(watch: WatchTarget): Promise<void> {\n    const schema = this.resolveSchema(watch);\n    if (!schema) {\n      logger.warn('TRANSCRIPT', 'Missing schema for watch', { watch: watch.name });\n      return;\n    }\n\n    const resolvedPath = expandHomePath(watch.path);\n    const files = this.resolveWatchFiles(resolvedPath);\n\n    for (const filePath of files) {\n      await this.addTailer(filePath, watch, schema);\n    }\n\n    const watchRoot = this.deepestNonGlobAncestor(resolvedPath);\n    if (!watchRoot || !existsSync(watchRoot)) {\n      logger.debug('TRANSCRIPT', 'Watch root does not exist, skipping fs.watch', { watch: watch.name, watchRoot });\n      return;\n    }\n\n    try {\n      const watcher = fsWatch(watchRoot, { recursive: true, persistent: true }, (event, name) => {","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/e2d1df569a8f04075d40e92461128ece7cf04c82/src/services/transcripts/watcher.ts#L98-L134","documentation":"When the transcript watcher sets up a watch target, resolveSchema() maps a string watch.schema to an entry in the config's top-level `schemas` map (an inline schema object is used as-is). If the string names a schema that does not exist in that map, the lookup returns null, this warning is logged, and the watch is skipped — no files are tailed for it.","triggerScenarios":"A watch declares \"schema\": \"codex\" (or any name) that has no matching key under `schemas` in the same transcript watch config JSON; the schema was renamed or removed, or the name has a typo/case mismatch.","commonSituations":"Upgrading claude-mem versions where bundled schema names changed; hand-editing the watch config and misspelling the schema reference; splitting config files so the watch and its schema definition end up in different files.","solutions":["Open the transcript watch config and check the exact keys under `schemas`; fix the watch's `schema` string to match one of them","Or replace the string with an inline schema object on the watch itself","After fixing, restart the worker so setupWatch runs again with the corrected config"],"exampleFix":"// before\n{ \"schemas\": { \"codex-v1\": { ... } }, \"watches\": [ { \"name\": \"codex\", \"schema\": \"codex\", \"path\": \"~/.codex/sessions/**/*.jsonl\" } ] }\n\n// after\n{ \"schemas\": { \"codex-v1\": { ... } }, \"watches\": [ { \"name\": \"codex\", \"schema\": \"codex-v1\", \"path\": \"~/.codex/sessions/**/*.jsonl\" } ] }","handlingStrategy":"validation","validationCode":"function assertWatchSchemasValid(config: TranscriptWatchConfig): void {\n  for (const watch of config.watches) {\n    if (typeof watch.schema === 'string' && !config.schemas?.[watch.schema]) {\n      throw new Error(`watch '${watch.name}' references unknown schema '${watch.schema}'`);\n    }\n  }\n}","typeGuard":"function hasResolvableSchema(watch: WatchTarget, schemas?: Record<string, TranscriptSchema>): boolean {\n  if (typeof watch.schema === 'string') return Boolean(schemas?.[watch.schema]);\n  return Boolean(watch.schema);\n}","tryCatchPattern":null,"preventionTips":["Keep schema definitions and the watches that reference them in the same config file","Run a config validator (like the snippet) in CI or before worker start","After renames, grep the watch config for old schema names"],"tags":["config","schema","transcript-watcher"],"backgroundTag":"schema-validation-failed","analyzedSha":"e2d1df569a8f04075d40e92461128ece7cf04c82","analyzedAt":"2026-08-20T23:58:13.836Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}