thedotmack/claude-mem · critical
schema v46: missing .
Error message
schema v46: missing ${target.table}.${target.column} What it means
During the schema-v46 migration (ensureSyncRevisionTextAffinity, run from the SessionStore constructor), PRAGMA table_info does not list the expected sync-revision column on the target table. This is an internal invariant: the migration assumes the column exists, and its absence means the schema is in an unexpected state, so startup aborts.
Solutions
- Restore a database backup taken before the failed migration
- Check which schema_versions rows exist and run the migration chain from a matching app version
- Recreate the database by deleting ~/.claude-mem/claude-mem.db if data is disposable
- Report the DB state (PRAGMA table_info output) as a bug if the column should exist
Defensive patterns
Strategy: try-catch
Validate before calling
// check target column exists before opening the store
const cols = db.query("PRAGMA table_info(sdk_sessions)").all();
if (!cols.some(c => c.name === 'sync_rev')) console.error('DB missing sync_rev; restore backup'); Try / catch
try { store = new SessionStore(dbPath); } catch (e) {
if (String(e.message).startsWith('schema v46: missing')) {
restoreBackupOrRebuild(dbPath); // fatal: cannot continue with this DB
} else throw e;
} Prevention
- Back up the database before upgrading app versions
- Never downgrade the app to a version older than the DB schema
- Don't hand-edit or subset a live database file
When it happens
Trigger: Opening a database whose schema is older/newer than expected such that sync_rev (or the other v46 target column) is missing from the target table when the v46 affinity migration runs.
Common situations: Restoring a partially migrated database file from backup; downgrading the app after a future schema version dropped the column; a corrupted or hand-edited database.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Column not found in , skipping rename
- schema v46: failed to copy
- schema v46: . row is REAL and unrecoverably rounded
- schema v46: . row has unsupported storage
- schema v46: . row is not a positive canonical uint64…
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/6af7a3c441fe46d6.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/sqlite/SessionStore.ts:707
const columnInfo = (table: string, column: string): TableColumnInfo | undefined =>
(this.db.query(`PRAGMA table_info(${table})`).all() as TableColumnInfo[])
.find(info => info.name === column);
const isText = (info: TableColumnInfo | undefined): boolean =>
info?.type.trim().toUpperCase() === 'TEXT';
const applied = this.db.prepare(
'SELECT version FROM schema_versions WHERE version = ?'
).get(46) as SchemaVersion | undefined;
if (applied && targets.every(target => isText(columnInfo(target.table, target.column)))) {
return;
}
const tx = this.db.transaction(() => {
for (const target of targets) {
const columns = this.db.query(`PRAGMA table_info(${target.table})`).all() as TableColumnInfo[];
const source = columns.find(info => info.name === target.column);
if (!source) {
throw new Error(`schema v46: missing ${target.table}.${target.column}`);
}
for (const raw of streamRows(this.db.query(`
SELECT CAST(id AS TEXT) AS row_id,
typeof(${target.column}) AS storage_type,
CAST(${target.column} AS TEXT) AS revision
FROM ${target.table}
`))) {
const row = raw as { row_id: string; storage_type: string; revision: string | null };
if (row.storage_type === 'real') {
throw new Error(
`schema v46: ${target.table}.${target.column} row ${row.row_id} is REAL and unrecoverably rounded`
);
}
if (row.storage_type !== 'integer' && row.storage_type !== 'text') {
throw new Error(
`schema v46: ${target.table}.${target.column} row ${row.row_id} has unsupported ${row.storage_type} storage`
);View on GitHub (pinned to d8bc9755e7)