Skip to content

fix(caldav): don't duplicate a task when a client PUTs a stale href - #3540

Merged
kolaente merged 1 commit into
mainfrom
agent/issue-3482
Aug 18, 2026
Merged

fix(caldav): don't duplicate a task when a client PUTs a stale href#3540
kolaente merged 1 commit into
mainfrom
agent/issue-3482

Conversation

@tink-bot

Copy link
Copy Markdown
Collaborator

CalDAV client PUTting task to collection task no longer lives in got second copy of that task created in that collection instead of error. iOS Reminders hits this every time it completes task it still believes lives in old project, so copies all carry STATUS:COMPLETED — and stay invisible in web UI, where done tasks hidden by default.

Cause: project consistency guard makes GetResource report task as missing for mismatched collection, so caldav-go PUT handler falls through to CreateResource. Now CreateResource refuses UID that already exists and returns 404, so client resyncs and finds task under real collection.

Fixes #3482

How to verify

  1. As user15, create a task over CalDAV in project 36:
    curl -u user15:<password> -X PUT \
      -H 'Content-Type: text/calendar' \
      --data-binary $'BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Vikunja//EN\r\nBEGIN:VTODO\r\nUID:stale-href-demo\r\nDTSTAMP:20230301T073337Z\r\nSUMMARY:Task G\r\nEND:VTODO\r\nEND:VCALENDAR' \
      https://<instance>/dav/projects/36/stale-href-demo.ics
    
  2. Simulate the stale client by PUTting the same UID, now completed, to a different project (38):
    curl -i -u user15:<password> -X PUT \
      -H 'Content-Type: text/calendar' \
      --data-binary $'BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Vikunja//EN\r\nBEGIN:VTODO\r\nUID:stale-href-demo\r\nDTSTAMP:20230301T073337Z\r\nSUMMARY:Task G\r\nSTATUS:COMPLETED\r\nEND:VTODO\r\nEND:VCALENDAR' \
      https://<instance>/dav/projects/38/stale-href-demo.ics
    
  3. Run a calendar-query REPORT against project 38, and open project 38 in the web UI with the "Show Done Tasks" filter enabled.
  4. Expected: the second PUT returns 404, the REPORT for project 38 contains no VTODO with that UID, and project 38 stays empty in the web UI. The task remains readable at /dav/projects/36/stale-href-demo.ics.
    Before this PR: the second PUT returned 201 and project 38 gained a duplicate completed copy of the task.

When a client PUT a task to a collection the task no longer lives in, the
project consistency guard made GetResource report it as missing, so the PUT
handler fell through to CreateResource and created a second copy of the task
in that project. iOS Reminders hits this whenever it completes a task it still
believes lives in the old project, which is why the copies all show up as
STATUS:COMPLETED - and stay invisible in the web UI, where done tasks are
hidden by default.

Refuse to create a task whose UID already exists, so the client resyncs and
finds the task under its real collection instead.
@kolaente
kolaente enabled auto-merge (rebase) August 18, 2026 09:07
@github-actions github-actions Bot added the area/caldav CalDAV / iCal sync with external calendar clients label Aug 18, 2026
@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview deployments for this PR are available at:

URL Tag Commit
https://pr-3540.preview.vikunja.dev ghcr.io/go-vikunja/vikunja:pr-3540 latest
https://sha-bca2d944db50dc0d79d75ae3243ba343267408e5.preview.vikunja.dev ghcr.io/go-vikunja/vikunja:sha-bca2d944db50dc0d79d75ae3243ba343267408e5 bca2d94

The preview environment will start automatically on first visit. Subsequent pushes to this PR will update the pr-3540 image — the preview picks up the new version on restart. The per-commit URLs point to a specific version and will not change.

Run locally with Docker
docker pull ghcr.io/go-vikunja/vikunja:pr-3540
docker run -p 3456:3456 ghcr.io/go-vikunja/vikunja:pr-3540

Last updated for commit bca2d94

@kolaente
kolaente merged commit 137d740 into main Aug 18, 2026
42 checks passed
@kolaente
kolaente deleted the agent/issue-3482 branch August 18, 2026 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/caldav CalDAV / iCal sync with external calendar clients

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CalDAV: completed tasks reported under wrong project's calendar

2 participants