fix(state-migrations): archive plugin install index on conflict instead of keeping it#90252
fix(state-migrations): archive plugin install index on conflict instead of keeping it#90252Bartok9 wants to merge 1 commit into
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed June 5, 2026, 5:20 AM ET / 09:20 UTC. Summary PR surface: Source -1, Tests +16. Total +15 across 2 files. Reproducibility: yes. Source inspection shows current main and v2026.6.1 return the conflict warning before archiving, so the same legacy file is re-read on the next migration run; I did not execute the test locally because this is a read-only review. Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the narrow archive-on-conflict migration after redacted real two-run upgrade proof and maintainer acceptance that the archived JSON is the conflict audit copy. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main and v2026.6.1 return the conflict warning before archiving, so the same legacy file is re-read on the next migration run; I did not execute the test locally because this is a read-only review. Is this the best way to solve the issue? Yes, this looks like the narrowest maintainable fix: reuse the existing archive path so the legacy JSON stops re-triggering while preserving it as AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 1a3ce7c2a8da. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source -1, Tests +16. Total +15 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
Per ClawSweeper review feedback [P3]: the previous text 'shared SQLite state has newer metadata for' was misleading — conflicts can arise from mismatched floating selectors, package renames, or malformed legacy spec metadata, not necessarily because SQLite is newer. Use a generic conflict description that accurately covers all conflict reasons.
f524018 to
ceb2111
Compare
|
@clawsweeper re-review Updated PR:
|
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
Summary
Motivation
Closes #90213.
After updating to OpenClaw 2026.6.1 (which merged the SQLite state migration in #88585 and the follow-up fix in #89281), some users saw:
This warning repeated on every gateway restart, every
openclaw doctor --fix, and everyopenclaw plugins inspectrun — because the legacy JSON file was left in place, causingmigrateLegacyInstalledPluginIndexto re-enter the conflict path on each invocation.Root cause (code trace)
In
src/infra/state-migrations.ts, the pre-patch conflict branch:This returns without calling
archiveLegacyInstalledPluginIndex, leavingplugins/installs.jsonon disk. On the next run, the file is re-read, the same conflict is re-detected, and the same warning fires again.Fix (code trace)
Post-patch — the conflict path now archives the file and continues:
archiveLegacyInstalledPluginIndexrenamesplugins/installs.json→plugins/installs.json.migrated. On subsequent runs, the file no longer exists atsourcePath, somigrateLegacyInstalledPluginIndexexits at the early-return guard before reaching the conflict branch — no repeated warning.Behavior proof (two-run trace)
Run 1 (fresh legacy file on disk, SQLite has conflicting records):
plugins/installs.json→ renamed toplugins/installs.json.migratedRun 2 (gateway restart /
openclaw doctor --fix/openclaw plugins inspect brave):The
sourcePathno longer exists, the migration function returns before the conflict branch, and warnings are empty. This is the fix behavior verified by the new regression test insrc/commands/doctor-state-migrations.test.ts(thesecond run produces no warningsassertion added by this PR).Verification
tsc --noEmit— cleandescribe('migrateLegacyInstalledPluginIndex — conflict archive')with parameterized cases covering:'shared SQLite state has newer metadata'to generic'detecting conflicting plugin install metadata'per ClawSweeper P3 feedback — covers all conflict causes, not just recency.