Skip to content

Panic (unwrap on None) reading sqlite-vec vec0 KNN results — SELECT ... WHERE embedding MATCH ? #229

Description

@klueless-io

Summary

Loading the sqlite-vec extension into a libsql database works, and a vec0 virtual table can be created, inserted into, and counted — but the KNN search query (... WHERE embedding MATCH ? ORDER BY distance) panics the native driver with called Option::unwrap() on a None value, aborting the process. This is the one operation that makes a vector extension useful, so sqlite-vec is effectively unusable via libsql.

Reproduced on both the latest stable libsql@0.5.29 and the latest prerelease libsql@0.6.0-pre.41.

Environment

  • libsql: 0.5.29 (and 0.6.0-pre.41)
  • sqlite-vec: 0.1.9
  • Node.js: v25.8.0
  • OS: macOS, arm64

Minimal reproduction

const Database = require('libsql');
const sqliteVec = require('sqlite-vec');

const db = new Database(':memory:');
sqliteVec.load(db);

console.log(db.prepare('select vec_version() v').get());          // ✓ works
db.exec('CREATE VIRTUAL TABLE t USING vec0(embedding float[4])'); // ✓ works
const f = a => Buffer.from(new Float32Array(a).buffer);
db.prepare('INSERT INTO t(rowid, embedding) VALUES (?, ?)').run(1n, f([1, 0, 0, 0])); // ✓ works
console.log(db.prepare('SELECT count(*) c FROM t').get());        // ✓ works -> { c: 1 }

// ✗ PANICS:
db.prepare('SELECT rowid, distance FROM t WHERE embedding MATCH ? ORDER BY distance LIMIT 1')
  .all(f([1, 0, 0, 0]));

Expected

The KNN query returns the nearest rows with their distance values (as it does under better-sqlite3 with the same extension).

Actual

thread '<unnamed>' panicked at src/statement.rs:396:62:
called `Option::unwrap()` on a `None` value

On 0.6.0-pre.41 the same query panics at src/lib.rs:1354:58 (fatal runtime error: failed to initiate panic, error 5, aborting).

Notes

  • load / CREATE VIRTUAL TABLE vec0 / INSERT / SELECT count(*) all succeed — only the vec0 KNN result (which surfaces the hidden distance column via the MATCH constraint) fails. The panic looks like the driver assuming column metadata that a vec0 virtual-table result doesn't provide.
  • The identical extension + query works under better-sqlite3.
  • A panic::catch_unwind (or graceful SqliteError) instead of an unwrap() would at least keep it recoverable, but the underlying goal is to read vec0 KNN results.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions