Merge pull request #389 from sonwr/fix-issue-380-cleanup-no-sqlite-vec

fix: skip cleanup when sqlite-vec is unavailable
This commit is contained in:
Tobias Lütke 2026-03-14 08:07:11 -04:00 committed by GitHub
commit 5b48bcb6c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 0 deletions

View File

@ -1820,6 +1820,16 @@ export function cleanupOrphanedVectors(db: Database): number {
return 0;
}
// The schema entry can exist even when sqlite-vec itself is unavailable
// (for example when reopening a DB without vec0 loaded). In that case,
// touching the virtual table throws "no such module: vec0" and cleanup
// should degrade gracefully like the rest of the vector features.
try {
db.prepare(`SELECT 1 FROM vectors_vec LIMIT 0`).get();
} catch {
return 0;
}
// Count orphaned vectors first
const countResult = db.prepare(`
SELECT COUNT(*) as c FROM content_vectors cv

View File

@ -15,6 +15,7 @@ import {
normalizeDocid,
isDocid,
handelize,
cleanupOrphanedVectors,
} from "../src/store";
// =============================================================================
@ -85,6 +86,33 @@ describe("Path Utilities", () => {
// Handelize Tests
// =============================================================================
describe("cleanupOrphanedVectors", () => {
test("returns 0 when vec table exists in schema but sqlite-vec is unavailable", () => {
const prepare = (sql: string) => {
if (sql.includes("sqlite_master") && sql.includes("vectors_vec")) {
return { get: () => ({ name: "vectors_vec" }) };
}
if (sql.includes("SELECT 1 FROM vectors_vec LIMIT 0")) {
return { get: () => { throw new Error("no such module: vec0"); } };
}
throw new Error(`Unexpected SQL in test: ${sql}`);
};
const db = {
prepare,
exec: () => {
throw new Error("cleanup should not execute vector deletes when sqlite-vec is unavailable");
},
} as any;
expect(cleanupOrphanedVectors(db)).toBe(0);
});
});
// =============================================================================
// Handelize Tests
// =============================================================================
describe("handelize", () => {
test("converts to lowercase", () => {
expect(handelize("README.md")).toBe("readme.md");