From 468dc55a392c1782e049c4c35a83d2813ebf06d6 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 12 Aug 2026 13:56:04 -0700 Subject: [PATCH] fix(matrix): silence empty inbound dedupe migration receipt on fresh installs (#122808) On a pristine profile, onboarding/doctor printed "Auto-migrated legacy state: Recorded Matrix inbound dedupe migration completion (0 SQLite roots, 0 JSON roots scanned)" even though nothing was migrated. Keep the durable empty-scan receipt (it still prevents later historical databases from being opened) but only emit the user-visible change line when at least one SQLite/JSON root was scanned. --- extensions/matrix/doctor-contract-api.test.ts | 8 ++++---- extensions/matrix/doctor-contract-api.ts | 10 +++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/extensions/matrix/doctor-contract-api.test.ts b/extensions/matrix/doctor-contract-api.test.ts index b9ebf4c748f2..628f9c0bac23 100644 --- a/extensions/matrix/doctor-contract-api.test.ts +++ b/extensions/matrix/doctor-contract-api.test.ts @@ -765,7 +765,7 @@ describe("matrix doctor contract state migrations", () => { await expect(migration.detectLegacyState(createMigrationParams(stateDir))).resolves.toBeNull(); }); - it("records an empty legacy scan and then skips historical databases", async () => { + it("records an empty legacy scan silently and then skips historical databases", async () => { const stateDir = tempDirs.make("openclaw-matrix-doctor-"); const migration = migrationById("matrix-inbound-dedupe-to-claimable-dedupe"); const params = createMigrationParams(stateDir); @@ -773,10 +773,10 @@ describe("matrix doctor contract state migrations", () => { await expect(migration.detectLegacyState(params)).resolves.toEqual({ preview: ["Matrix inbound dedupe legacy sources need a one-time migration scan"], }); + // Fresh installs scan nothing: the durable receipt is recorded (proven by + // the historical-database skip below) without a user-visible change line. await expect(migration.migrateLegacyState(params)).resolves.toEqual({ - changes: [ - "Recorded Matrix inbound dedupe migration completion (0 SQLite roots, 0 JSON roots scanned)", - ], + changes: [], warnings: [], }); const lateDatabasePath = path.join( diff --git a/extensions/matrix/doctor-contract-api.ts b/extensions/matrix/doctor-contract-api.ts index df3c61fffb43..524d6bf9f9a8 100644 --- a/extensions/matrix/doctor-contract-api.ts +++ b/extensions/matrix/doctor-contract-api.ts @@ -346,9 +346,13 @@ export const stateMigrations: PluginDoctorStateMigration[] = [ } try { await recordMatrixInboundDedupeMigrationCompletion(params.context, params.env); - changes.push( - `Recorded Matrix inbound dedupe migration completion (${sources.sqliteRoots.length} SQLite roots, ${sources.jsonRoots.length} JSON roots scanned)`, - ); + // Fresh installs scan zero roots; keep the durable receipt silent + // there so onboarding doesn't report a migration that touched nothing. + if (sources.sqliteRoots.length + sources.jsonRoots.length > 0) { + changes.push( + `Recorded Matrix inbound dedupe migration completion (${sources.sqliteRoots.length} SQLite roots, ${sources.jsonRoots.length} JSON roots scanned)`, + ); + } } catch (err) { warnings.push( `Failed recording Matrix inbound dedupe migration completion: ${String(err)}`,