{"record":{"id":"3ef392b55754101b","repo":"thedotmack/claude-mem","slug":"fts-fallback-failed-for-timeline","errorCode":null,"errorMessage":"FTS fallback failed for timeline","messagePattern":"FTS fallback failed for timeline","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/services/worker/SearchManager.ts","lineNumber":798,"sourceCode":"\n      if (this.chromaSync) {\n        logger.debug('SEARCH', 'Using hybrid semantic search for timeline query', {});\n        try {\n          results = await this.searchChromaForTimeline(query, project, platformSource);\n        } catch (chromaError) {\n          const errorObject = chromaError instanceof Error ? chromaError : new Error(String(chromaError));\n          logger.error('WORKER', 'Chroma search failed for timeline, continuing without semantic results', {}, errorObject);\n        }\n      }\n\n      if (results.length === 0) {\n        try {\n          const ftsResults = this.sessionSearch.searchObservations(query, { project, platformSource, limit: 1 });\n          if (ftsResults.length > 0) {\n            results = ftsResults;\n          }\n        } catch (ftsError) {\n          logger.warn('SEARCH', 'FTS fallback failed for timeline', {}, ftsError instanceof Error ? ftsError : undefined);\n        }\n      }\n\n      if (results.length === 0) {\n        return {\n          content: [{\n            type: 'text' as const,\n            text: `No observations found matching \"${query}\". Try a different search query.`\n          }]\n        };\n      }\n\n      const topResult = results[0];\n      anchorId = topResult.id;\n      anchorEpoch = topResult.created_at_epoch;\n      logger.debug('SEARCH', 'Query mode: Using observation as timeline anchor', { observationId: topResult.id });\n      timelineData = this.sessionStore.getTimelineAroundObservation(topResult.id, topResult.created_at_epoch, depthBefore, depthAfter, project, platformSource);\n    }","sourceCodeStart":780,"sourceCodeEnd":816,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/worker/SearchManager.ts#L780-L816","documentation":"Logged when the FTS (full-text search) fallback used to backfill timeline results throws. The primary timeline search returned no results, and the fallback call to sessionSearch.searchObservations failed; the failure is swallowed and the flow continues to the empty-results branch.","triggerScenarios":"searchTimeline's primary search yields nothing, then the fallback this.sessionSearch.searchObservations(query, {project, platformSource, limit:1}) throws (e.g. corrupt/missing FTS index, SQL error).","commonSituations":"SQLite FTS table missing or corrupted after upgrade/migration; database locked by another process; query syntax issues escaping the FTS layer.","solutions":["Check the ftsError detail in the log payload to find the underlying SQLite/FTS failure.","Rebuild the FTS index for the sessions database.","Verify database file integrity and that no other process holds a write lock.","The tool still returns a valid empty-results response — treat this as degraded search, not data loss."],"exampleFix":"// after migration\nINSERT INTO observations(observations) VALUES('rebuild');","handlingStrategy":"fallback","validationCode":"// verify FTS index health before searching\nconst ok = db.prepare(\"SELECT count(*) FROM observations WHERE observations MATCH 'test'\").get();","typeGuard":null,"tryCatchPattern":"try {\n  results = sessionSearch.searchObservations(query, opts);\n} catch (e) {\n  logger.warn('FTS fallback failed', { error: e });\n  results = []; // degrade gracefully to empty results\n}","preventionTips":["Run FTS index rebuilds after schema migrations","Check SQLite FTS5 extension availability in your build","Treat empty search results plus this warning as an index-health signal"],"tags":["search","fts","fallback"],"backgroundTag":"database-query-failed","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"}