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
{{ message }}
Repository navigation
Non-finite vector components are accepted without error; resulting NULL / ±Infinity cosine distances sort ahead of the true nearest neighbor (v0.1.9) #325
sqlite-vec accepts vectors containing non-finite float32 components (NaN, +Inf) without any error, in both vec0 tables and the scalar distance functions. The resulting cosine distances are then non-finite, and in a MATCH query SQLite's ordering places the broken rows AHEAD of the true nearest neighbor.
Corpus in a vec0 cosine table: id1 = [0.9, 0.1] (the true nearest to query [1, 0], distance 0.0062), id2 = [NaN, 1], id3 = [Inf, 1] — all three inserts succeed:
SELECT id, distance FROM t WHERE v MATCH vec_f32('[1,0]') AND k =3ORDER BY distance;
-- (2, NULL), (3, NULL), (1, 0.006116...)
The two corrupt rows rank FIRST (SQLite sorts NULL before every value), and the actual nearest neighbor is displaced to the last position. Scalar functions are equally affected: vec_distance_cosine('[1,0]', '[NaN,1]') = NULL, and pairs involving +Inf return ±Infinity (see companion report on small-norm vectors for the same functions returning ±Inf on finite input).
Expected Behavior
Either reject non-finite components at insert/argument time with a clear error (the precedent exists in the ecosystem: pgvector rejects with "NaN not allowed in vector", Qdrant treats rejection as the correct boundary behavior in #9378), or define and document their distance semantics — but a NULL distance that sorts as better than every finite distance turns any threshold or top-k use into silently wrong results.
Steps to Reproduce
reproduce.py --output observed.json (Python 3 + sqlite-vec only, in-memory DB, cleans up nothing since it creates no files). It inserts the three rows, runs the MATCH query and the scalar calls, prints everything, and exits non-zero unless the nearest row ranks first and all distances are finite in [0, 2]. Deterministic; observed.json is from an actual run, executed twice with identical results.
sqlite-vec v0.1.9 via vec_version(), bundled through the sqlite-vec Python package, SQLite 3.x, Python 3.12, Windows 11
In-memory database; distance_metric=cosine table, no other extensions
The issue was found while checking that adding rows cannot change other rows' nearest-neighbor identity or score finiteness. This is the input-validation side of the float32-robustness cluster reported separately for small-norm vectors (NULL/±Inf there arise from finite input); here the trigger is non-finite input, accepted without error.
Activity