{"record":{"id":"381543be7471de59","repo":"thedotmack/claude-mem","slug":"schema-v48-invalid-v47-applied-at-applied-appli","errorCode":null,"errorMessage":"schema v48: invalid v47 applied_at ${applied.applied_at}","messagePattern":"schema v48: invalid v47 applied_at (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/services/sqlite/SessionStore.ts","lineNumber":909,"sourceCode":"        this.db.prepare('INSERT INTO schema_versions (version, applied_at) VALUES (?, ?)').run(47, appliedAt);\n        this.db.prepare('INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)').run(48, appliedAt);\n      });\n      tx();\n      return;\n    }\n\n    // Repair databases that ran the earlier v47 implementation before the\n    // explicit exclusion ledger existed. v47 stamped the launch baseline at\n    // its applied_at millisecond. Rows still stamped at/before that boundary\n    // are the excluded launch revisions; NULL or later stamps are post-launch\n    // writes/acks and must remain eligible for an epoch rebuild.\n    const exclusionsApplied = this.db.prepare(\n      'SELECT version FROM schema_versions WHERE version = ?'\n    ).get(48) as SchemaVersion | undefined;\n    if (exclusionsApplied && exclusionTableExisted) return;\n    const boundaryMs = Date.parse(applied.applied_at);\n    if (!Number.isSafeInteger(boundaryMs) || boundaryMs < 0) {\n      throw new Error(`schema v48: invalid v47 applied_at ${applied.applied_at}`);\n    }\n    const repair = this.db.transaction(() => {\n      for (const { table, kind } of tables) {\n        this.db.prepare(`\n          INSERT OR IGNORE INTO sync_launch_exclusions (kind, origin_local_id, through_rev)\n          SELECT ?, CAST(id AS TEXT), CAST(sync_rev AS TEXT)\n          FROM ${table}\n          WHERE origin_device_id IS NULL\n            AND synced_at > 0\n            AND synced_at <= ?\n        `).run(kind, boundaryMs);\n      }\n      this.db.prepare('INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)')\n        .run(48, new Date().toISOString());\n    });\n    repair();\n  }\n","sourceCodeStart":891,"sourceCodeEnd":927,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/sqlite/SessionStore.ts#L891-L927","documentation":"When initializing the sync hub launch baseline (schema v48), the migration derives a time boundary from the v47 migration's recorded applied_at timestamp. If that stored timestamp cannot be parsed to a safe, non-negative epoch ms, the recorded migration metadata is corrupt and startup aborts rather than computing a wrong exclusion boundary.","triggerScenarios":"initializeSyncRevisionBaseline runs on a DB where schema_versions has v47 recorded but its applied_at is empty, malformed (non-ISO), negative, or not a safe integer when parsed with Date.parse.","commonSituations":"Hand-edited or partially restored schema_versions table; a clock/serialization bug when v47 was originally applied; copying rows between DBs with wrong timestamp formats.","solutions":["Inspect: SELECT applied_at FROM schema_versions WHERE version = 47 and fix it to a valid ISO 8601 UTC timestamp","Restore a backup of the database from before v47/v48","Rebuild the database if historical sync-exclusion boundaries are not needed","Report as a bug if applied_at was never hand-modified"],"exampleFix":"-- before\napplied_at = 'yesterday'\n-- after\nUPDATE schema_versions SET applied_at = '2026-09-17T12:00:00.000Z' WHERE version = 47;","handlingStrategy":"try-catch","validationCode":"const v47 = db.prepare('SELECT applied_at FROM schema_versions WHERE version = 47').get();\nconst ok = v47 && Number.isSafeInteger(Date.parse(v47.applied_at)) && Date.parse(v47.applied_at) >= 0;\nif (v47 && !ok) console.error('Corrupt v47 applied_at:', v47.applied_at);","typeGuard":null,"tryCatchPattern":"try { store = new SessionStore(dbPath); } catch (e) {\n  if (String(e.message).startsWith('schema v48: invalid v47 applied_at')) {\n    restoreBackupOrRepairTimestamp(dbPath);\n  } else throw e;\n}","preventionTips":["Never hand-edit schema_versions rows","Verify timestamps are ISO 8601 when copying DB data between environments","Back up the DB before version upgrades"],"tags":["schema","migration","sqlite","timestamp"],"backgroundTag":"schema-validation-failed","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}