thedotmack/claude-mem · critical

schema v46: unexpected temporary column

Error message

schema v46: unexpected temporary column ${target.table}.${target.temporary}

What it means

Before the v46 migration adds its temporary TEXT column, it verifies the temporary column does not already exist. If it does, a previous migration attempt left the table half-migrated (or was interrupted mid-transaction), and continuing could corrupt data, so it throws.

Solutions

  1. Restore a database backup from before the interrupted migration
  2. Inspect the table: PRAGMA table_info(<table>) and drop leftover temp columns only if their data is redundant
  3. Delete and rebuild the database if the data is expendable
  4. Report as a bug if it reproduces on a healthy DB

Example fix

-- inspect leftover migration state
PRAGMA table_info(sdk_sessions);
-- if safe, let migration restart from a clean pre-v46 backup instead of hand-editing
Defensive patterns

Strategy: try-catch

Validate before calling

const cols = db.query('PRAGMA table_info(sdk_sessions)').all();
if (cols.some(c => String(c.name).startsWith('__tmp') || c.name.includes('_tmp_'))) {
  console.error('Leftover migration temp column; restore backup');
}

Try / catch

try { store = new SessionStore(dbPath); } catch (e) {
  if (String(e.message).includes('unexpected temporary column')) {
    restoreBackup(dbPath); // do NOT hand-drop the temp column blindly
  } else throw e;
}

Prevention

When it happens

Trigger: ensureSyncRevisionTextAffinity finds target.temporary (the shadow column added before copy/drop/rename) already present in PRAGMA table_info for the target table.

Common situations: A crashed/killed process left a partially applied migration (SQLite DDL is transactional here, but a foreign/older copy of the DB may contain leftovers); restoring a DB dump taken mid-migration.

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


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/bd89408cf46a9bf9. Report an issue: GitHub.

Appendix: source

Thrown at src/services/sqlite/SessionStore.ts:738

            );
          }
          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`
            );
          }
          try {
            assertCanonicalDecimal(row.revision, { positive: true });
          } catch {
            throw new Error(
              `schema v46: ${target.table}.${target.column} row ${row.row_id} is not a positive canonical uint64 revision`
            );
          }
        }

        if (isText(source)) continue;
        if (columns.some(info => info.name === target.temporary)) {
          throw new Error(`schema v46: unexpected temporary column ${target.table}.${target.temporary}`);
        }

        this.db.run(
          `ALTER TABLE ${target.table} ADD COLUMN ${target.temporary} TEXT NOT NULL DEFAULT '1'`
        );
        this.db.run(
          `UPDATE ${target.table} SET ${target.temporary} = CAST(${target.column} AS TEXT)`
        );
        const mismatch = this.db.prepare(`
          SELECT CAST(id AS TEXT) AS row_id
          FROM ${target.table}
          WHERE ${target.temporary} <> CAST(${target.column} AS TEXT)
          LIMIT 1
        `).get() as { row_id: string } | undefined;
        if (mismatch) {
          throw new Error(
            `schema v46: failed to copy ${target.table}.${target.column} row ${mismatch.row_id} exactly`
          );

View on GitHub (pinned to d8bc9755e7)