Fix Jetpack backup import using stale .ht.sqlite instead of SQL dumps#3144
Conversation
When a Jetpack backup contains both SQL dumps (sql/*.sql) and a wp-content/database/.ht.sqlite file, PlaygroundValidator matches first and copies the stale SQLite file directly—ignoring the SQL dumps that contain the actual up-to-date data. This happens when a site was previously used with Studio, leaving a .ht.sqlite in wp-content/ that gets swept into subsequent Jetpack backups from the production MySQL site. Two fixes: - PlaygroundValidator now defers to JetpackValidator when SQL dumps are present alongside .ht.sqlite - JetpackValidator now excludes wp-content/database/ from the file copy list, preventing the stale .ht.sqlite from overwriting the freshly imported database
katinthehatsite
left a comment
There was a problem hiding this comment.
The changes look good to me and I was able to import the file correctly. I also did not see any further regressions 👍
Do you think we should add some tests to cover for this scenario?
|
Thank you for the review, Kat!
Good idea! I have added them in 1cc5ac3. |
📊 Performance Test ResultsComparing 1cc5ac3 vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
epeicher
left a comment
There was a problem hiding this comment.
Thanks @ivan-ottinger for the fix, this was a great sleuthing! I have tested it, and I can confirm that importing one of the suggested sites works as expected on this branch compared with the production site, while on trunk, the imported site is different. Changes also LGTM! ![]()
Related issues
Proposed Changes
sql/directory), deferring toJetpackValidatorwhich uses the SQL dumps as the authoritative data sourcewp-content/database/from the wp-content file copy list as a defensive measure, following the same pattern used inmoveExistingWpContentToTrashContext
When a Jetpack backup contains both SQL dumps (
sql/*.sql) and awp-content/database/.ht.sqlitefile,PlaygroundValidatormatches first (it's checked beforeJetpackValidatorin the importer options) and copies the stale SQLite file directly as the database — completely ignoring the SQL dumps.This happens when a site was previously used with Studio, leaving a
.ht.sqliteinwp-content/that gets swept into subsequent Jetpack backups from the production MySQL site. The.ht.sqlitemay be weeks or months out of date, causing silent data loss — missing posts, revisions, and outdated page content with no error reported.I was also checking how that old
.ht.sqliteDB file could have gotten to the Jetpack backup. For now it looks like it was some manual process the user took (as they were moving sites previously). I don't see any way we would have included the file in there ourselves. Maybe there was some bug in Studio previously, but I don't see any issues on that front at the moment.Testing Instructions
npm start.wp-content/database/.ht.sqlite. You can use real example backups from here: 3aff6-pb.How AI was used in this PR
Claude Code investigated why Jetpack backup imports produced sites with missing posts. Through iterative debugging — with manual testing and verification at each step — we traced the root cause to
PlaygroundValidatormatching a stale.ht.sqlitebeforeJetpackValidator, and implemented the fix.Pre-merge Checklist