You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
memory recall (and the dashboard Memory search) no longer fault on queries containing FTS5 metacharacters. A query bearing -, ., :, (, ), *, or a bare-word AND/OR/NOT — e.g. cut-release, v1.11.0 — was bound straight into items_fts MATCH ? unescaped, so FTS5 parsed the metacharacters as query syntax and raised SQLITE_ERROR, surfaced to the user as the opaque internal: fts: sqlite error (code 1): internal. The fusion FTS arm now escapes the query at a single seam (internal/ftsquery): each whitespace token is wrapped as a double-quoted FTS5 string literal (embedded quotes doubled; NUL bytes and invalid UTF-8 stripped, since SQLite treats text as NUL-terminated and an embedded NUL truncates the MATCH expression), and the literals are joined — implicit-AND for general recall, OR under --on-error (preserving the RESOLVES-walk seeding). The error-recall reflex's buildQuery, which previously carried its own copy of this escaping, now passes raw blended text through that same seam, removing the duplicate. Latent since the retrieval layer was introduced; the escaping previously existed only on the error-recall path and was never retrofitted to the general path. A query that escapes to no matchable token (whitespace-only, or content that is entirely metacharacters / NUL / invalid UTF-8) now skips both FTS arms and logs a retrieval.fts.skipped warning — symmetric with the existing vec-arm skip log — instead of binding an empty MATCH ''.
memory recall no longer faults on the first recall against a cold/empty vector index when a real embedder is configured.vec1's flat items_vec index has dimension 0 until its first vector insert, so a KNN bound with a non-zero-dim query vector — e.g. the embedding of an ordinary query like foo — raised SQLITE_ERROR (vec1: unexpected vector blob size N bytes, expected 0), surfaced to the user as the opaque internal: vec knn: sqlite error (code 1): internal. This hit the cold-start path: a real embedder enabled but nothing embedded yet (empty vec_index_map / items_vec), or any otherwise-empty vector index — the first recall on a fresh DB before anything is saved. It was masked until now only because the default OFFLINE / stub embedder short-circuits the vec arm (via intake.ErrStubEmbedderUnavailable) before KNN ever runs. vecKNN now short-circuits to an empty result when vec_index_map is empty — the bridge is co-populated with items_vec on every save and is the KNN's JOIN target, so an empty map yields an empty result regardless — enforcing the function's already-documented "empty result is not an error" contract for the cold-index case. A populated index still runs the KNN unchanged, so a genuine vec fault on a non-empty index still propagates as internal. Independent of the FTS5-escaping fix above; discovered while testing it.