Repository navigation
fix(file-provider): drop a row whose folder is gone from the server - #11025
juliusvaart wants to merge 1 commit into
Conversation
3d88640 to
38bf9c0
Compare
|
Hello there, We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process. Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6 Thank you for contributing to Nextcloud and we hope to hear from you soon! (If you believe you should not receive this message, you can add yourself to the blocklist.) |
A metadata row whose parent folder no longer exists on the server was
never cleaned up. The working-set scan does not reach it when the item
is not materialised, and no depth-1 read of the vanished folder will
ever report it as deleted. Every lookup of the item fell through to
parentItemIdentifierWithRemoteFallback, read the folder, got 404 and
failed again, for example once per item on each framework cache
refresh after an update ("Not modifying item because it was not
found.").
When that read returns 404 and the item is not materialised, mark the
row deleted. Nothing can exist below a folder the server no longer has.
Materialised items are left to the working-set scan, which already
handles them, so a rename of their folder still in flight cannot drop a
downloaded file. Any other read failure leaves the row alone. If the
item has in fact moved, its next read restores the row by its
identifier.
Assisted-by: ClaudeCode:claude-opus-5-5
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Julius van der Vaart <julius@vanderva.art>
38bf9c0 to
1c5eb7f
Compare
Resolves
No issue filed. Found while testing on a live account.
Summary
A metadata row whose parent folder no longer exists on the server is never cleaned up.
On the test account, four
.inddfiles had rows under…/2026_Kaarten/Ontwerp/, a folder that no longer existed at that path on the server. As it turned out, it had been moved to02_DESIGN/oud, files included. Nothing removed or corrected those rows:Every lookup of such an item goes through
parentItemIdentifierWithRemoteFallback, reads the folder, gets 404, and fails again. In practice that means a burst of errors per item on each framework cache refresh after an update:At the first such refresh macOS also answered
requestModificationwith "the file does not exist". The system had never known these items; they only lived in the database.The fix
When the parent read returns 404 and the item is not materialised (not a downloaded file, not a visited folder), the row is marked deleted. Nothing can exist below a folder the server no longer has.
The change is 8 lines in
FilesDatabaseManager.parentItemIdentifierWithRemoteFallback.Tests
New
ParentRemoteFallbackTests:testARowWhoseFolderIsGoneFromTheServerIsMarkedDeleted: the regression test. It fails without the fix and passes with it.testADownloadedFileIsLeftToTheScan,testAVisitedFolderIsLeftToTheScan,testAnotherReadFailureLeavesTheRowAlone,testAFolderThatStillExistsResolvesWithoutTouchingTheRow: guards. They pass both before and after.Full suite, run locally with
swift test:3527955c09.EnumeratorTestscases, and swift-testing runs occasionally crash inswiftpm-testing-helper. Both also happen on unmodified master. The reruns were clean.swiftformat --lint .is clean.The same commit also applies and passes on top of #11004 (GRDB), once the test's initializer call gets
try.Moved rather than deleted
In the case above the files had moved, not gone. Later, a system-initiated re-listing (
fileproviderdstream reset) read02_DESIGN/oudand corrected all four rows by their identifiers. With this change the rows would have been marked deleted in between, and then restored by that same read: rows are matched by identifier, and the server payload carriesdeleted = false. Because these items were neither downloaded nor known to the system, nothing visible changes in between.Not verified
Checklist
AI (if applicable)
The code, tests and this description were written by Claude Code (Claude Opus 5.5) at my request, from a diagnosis of my own account's logs and database.
🤖 Generated with Claude Code