Skip to content

Commit 7dd46ee

Browse files
lishuceoclaude
andcommitted
fix(memory): 修复旧 DB 启动时 repository 列缺失导致崩溃循环
PR #249 在 CREATE TABLE 中加了 repository 列,但 IF NOT EXISTS 对存量 DB 会跳过;紧接其后的 CREATE INDEX ON memories(repository) 在不存在 的列上建索引,直接抛 SqliteError,启动失败,服务 PM2 崩溃循环。 删除冲突的索引创建语句,归属 migrationV3 单一来源(ALTER TABLE 后建索引)。 附带回归测试:构造 pre-v3 schema DB,验证 create 不再抛错且会补列。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent e7f876b commit 7dd46ee

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

src/memory/__tests__/database.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,50 @@ describe('MemoryDatabase', () => {
407407
db2.close();
408408
});
409409

410+
it('should open a legacy DB that pre-dates the repository column without crashing', async () => {
411+
// Regression for PR #249: CREATE INDEX on memories(repository) ran *before*
412+
// migration v3 added the column, crashing startup against any pre-existing DB.
413+
db.close();
414+
415+
// Build a legacy schema by hand — pre-v3, no `repository` column.
416+
const Database = (await import('better-sqlite3')).default;
417+
const legacyPath = join(tempDir, 'legacy.db');
418+
const raw = new Database(legacyPath);
419+
raw.exec(`
420+
CREATE TABLE memories (
421+
id TEXT PRIMARY KEY,
422+
agent_id TEXT NOT NULL,
423+
user_id TEXT,
424+
chat_id TEXT,
425+
workspace_dir TEXT,
426+
type TEXT NOT NULL,
427+
content TEXT NOT NULL,
428+
tags TEXT DEFAULT '[]',
429+
metadata TEXT DEFAULT '{}',
430+
confidence REAL NOT NULL DEFAULT 1.0,
431+
confidence_level TEXT NOT NULL DEFAULT 'L0',
432+
evidence_count INTEGER NOT NULL DEFAULT 1,
433+
valid_at TEXT NOT NULL,
434+
invalid_at TEXT,
435+
superseded_by TEXT,
436+
ttl TEXT,
437+
source_chat_id TEXT,
438+
source_message_id TEXT,
439+
created_at TEXT NOT NULL,
440+
updated_at TEXT NOT NULL,
441+
last_accessed_at TEXT
442+
);
443+
`);
444+
raw.pragma('user_version = 0');
445+
raw.close();
446+
447+
// Should NOT throw "SQLITE_ERROR: no such column: repository".
448+
const migrated = await MemoryDatabase.create(legacyPath);
449+
const cols = migrated.db.prepare(`PRAGMA table_info(memories)`).all() as Array<{ name: string }>;
450+
expect(cols.some(c => c.name === 'repository')).toBe(true);
451+
migrated.close();
452+
});
453+
410454
it('should not re-run migrations on subsequent opens', async () => {
411455
db.close();
412456

src/memory/database.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,6 @@ export class MemoryDatabase {
248248
CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
249249
CREATE INDEX IF NOT EXISTS idx_memories_valid ON memories(invalid_at);
250250
CREATE INDEX IF NOT EXISTS idx_memories_workspace ON memories(workspace_dir);
251-
CREATE INDEX IF NOT EXISTS idx_memories_repository ON memories(repository);
252251
`);
253252

254253
// vec0 virtual table (conditional, with cosine distance)

0 commit comments

Comments
 (0)