Skip to content

fix: create the missing destination folder when retrying an automatic upload - #5033

Open
RaphaelFakhri wants to merge 3 commits into
owncloud:masterfrom
RaphaelFakhri:fix/automatic_uploads_double_separator
Open

RaphaelFakhri wants to merge 3 commits into
owncloud:masterfrom
RaphaelFakhri:fix/automatic_uploads_double_separator

Conversation

@RaphaelFakhri

@RaphaelFakhri RaphaelFakhri commented Oct 24, 2026 •

Copy link
Copy Markdown

Related Issues

App: Fixes #4451

Main problem: retried automatic uploads end in Conflict

A failed automatic upload is retried through UploadFileFromFileSystemWorker, not UploadFileFromContentUriWorker. On its first attempt, UploadFileFromContentUriWorker.copyFileToLocalStorage() copies the picture to the app cache and replaces the transfer's localPath with that cached file. On retry the path is no longer a content URI, so RetryFailedUploadsUseCase goes through RetryUploadFromSystemUseCase.

UploadFileFromFileSystemWorker.checkParentFolderExistence() built its existence check with isUserLoggedIn = false. With that flag, CheckPathExistenceRemoteOperation ignores remotePath and sends PROPFIND to the base WebDAV URL /remote.php/dav/files/. That URL always exists, so the check returns 207 and the missing destination folder is never created. The PUT then gets 409 Files cannot be created in non-existent collections, which is stored as Conflict. The OC10 log in the issue shows exactly this sequence:

Existence check for http://TEST/remote.php/dav/files/ finished with HTTP status 207
Existence check for http://TEST/remote.php/dav/files/admin/CameraUpload/20240813_105637.jpg finished with HTTP status 404(FAIL)
PUT http://TEST/remote.php/dav/files/admin/CameraUpload/20240813_105637.jpg -> 409 Sabre\DAV\Exception\Conflict

The fix passes isUserLoggedIn = AccountUtils.getCurrentOwnCloudAccount(appContext) != null, as UploadFileFromContentUriWorker and the name collision check already do. The check then queries /remote.php/dav/files/<user>/<folder>/ and CreateRemoteFolderOperation creates the folder when it is missing.

Secondary: double separator in the remote path

Folders picked as the automatic uploads destination can store their path with a trailing separator (for example, /Bbbbb/), and AutomaticUploadsWorker appended another one before the file name. The remote path is now composed through FolderBackUpConfiguration.getRemotePathForFile(), which trims it. This does not cause the conflict and can be split into its own PR if preferred.

  • Add changelog files for the fixed issues in folder changelog/unreleased. More info here
  • Add feature to Release Notes in ReleaseNotesViewModel.kt creating a new ReleaseNote() with String resources (if required): not required

QA

  • ./gradlew detekt :owncloudDomain:testDebugUnitTest :owncloudApp:compileOriginalDebugKotlin :owncloudApp:testOriginalDebugUnitTest passes (117 app unit tests).
  • FolderBackUpConfigurationTest covers the separator change.
  • The upload workers have no unit tests, and I have not run the app against a server, so the conflict fix still needs a manual check with the steps from the issue: enable automatic uploads for pictures to a folder that does not exist yet, take pictures with the server off, switch it on, and retry. The uploads should succeed, the folder should be created, and the log should show the existence check against /remote.php/dav/files/<user>/<folder>/ followed by MKCOL.
  • Not covered: the second scenario in the issue (uploads shown as uploaded while the server is off after switching accounts) looks like a separate problem.

Signed-off-by: Raphael Fakhri <153192858+RaphaelFakhri@users.noreply.github.com>
@RaphaelFakhri
RaphaelFakhri requested a review from a team as a code owner October 24, 2026 20:08
@CLAassistant

CLAassistant commented Oct 24, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Signed-off-by: Raphael Fakhri <153192858+RaphaelFakhri@users.noreply.github.com>
@jesmrec

jesmrec commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

@RaphaelFakhri thanks a lot for your contribution! we'll check it as soon as we have some time for it 😅 . Keep tuned, we could ask you for code review changes or fixes in the code! It's cool to check that the commits are verified and follow the conventional commits convention 💯

Just one consideration: you must sign the CLA, otherwise the PR will not move forward.

@RaphaelFakhri

Copy link
Copy Markdown
Author

Thanks for taking a look. The CLA is already signed for this PR: the CLA assistant check reports that all committers have signed (status).

@jesmrec

jesmrec commented Oct 28, 2026

Copy link
Copy Markdown
Member

About the solution here, my feeling is that you put the focus in the double slash // as was commented in the issue. But, that was just a guess, just in case it affects to the main problem. And, the main problem is not fixed here (i just reproduced it).

This is, a failed automatic upload is marked as Conflict after a retry. Server returns 409 (it could be involved, not a statement). Please, take a deeper look to the issue to understand the main problem, reconsider the fix, and come back to us if you have further questions. Happy to help.

UploadFileFromFileSystemWorker checked the parent folder with
isUserLoggedIn = false, which makes CheckPathExistenceRemoteOperation
ignore the path and query the base WebDAV URL. That URL always exists, so
a missing destination folder was never created and the PUT failed with
409, marking the upload as a conflict.

A failed automatic upload is retried through this worker because the
first attempt replaces its content URI with the cached copy, so the
retry always hit this check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@RaphaelFakhri RaphaelFakhri changed the title fix: avoid a double separator in automatic uploads remote path fix: create the missing destination folder when retrying an automatic upload Oct 28, 2026
@RaphaelFakhri

Copy link
Copy Markdown
Author

@jesmrec thanks for reproducing it, you were right. I found the real cause and pushed a fix in 3efc219.

A failed automatic upload is retried through UploadFileFromFileSystemWorker, because the first attempt replaces the content URI with the cached copy of the picture. That worker checked the destination folder with isUserLoggedIn = false, which makes CheckPathExistenceRemoteOperation ignore the path and query /remote.php/dav/files/. That always returns 207, so the missing folder was never created, and the PUT got the 409 Files cannot be created in non-existent collections that ends up as Conflict. The log in the issue shows it: Existence check for http://TEST/remote.php/dav/files/ finished with HTTP status 207 right before the 409. The fix passes the same flag the content URI worker already uses, so the check queries the real folder and creates it when needed.

I kept the double separator change as a secondary fix, but I can move it to its own PR or drop it if you prefer. I have no test server here, so I checked the fix by tracing the code against the logs. Detekt, the build and the unit tests pass. I updated the description with the details and the manual steps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Auto uploads result in a conflict status when trying to retry them

3 participants