nextcloud / nextcloud/integration_davc

Empty DAV resourcetype causes contacts and calendar objects to be skipped

Open Beginner friendly
#168 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
PHP
Stars
12
Forks
2
Avg merge
1d 21h
Merged PRs (30d)
16

Description

Disclaimer : I heavily used AI (ChatGPT) to debug this, I may not understand everything, I'm not an IT pro.

Steps to reproduce
  1. Configure DAV Connector to connect to a Radicale server providing CardDAV and CalDAV collections.
  2. Use Radicale with radicale_storage_decsync as the storage backend.
  3. Add a remote contacts or calendar collection in DAV Connector.
  4. Enable the collection and run Harmonize.
  5. The collection itself is discovered correctly, but individual contacts/events are not imported.

Radicale returns a DAV resourcetype property for individual .vcf and .ics resources with an empty value.

After parsing by DAV Connector/Sabre, DAV_RESOURCE_TYPE is therefore not null, but:

$resource[200][RemoteClient::DAV_RESOURCE_TYPE]->getValue()

returns:

[]

The current checks in both RemoteContactsService.php and RemoteEventsService.php skip these resources because they only test whether DAV_RESOURCE_TYPE exists and is non-null.

For example:

if (
    isset($resource[200][RemoteClient::DAV_RESOURCE_TYPE])
    && $resource[200][RemoteClient::DAV_RESOURCE_TYPE] !== null
) {
    continue;
}

The same logic is also present in the corresponding entityDelta() processing.

I tested the following additional condition:

if (
    isset($resource[200][RemoteClient::DAV_RESOURCE_TYPE])
    && $resource[200][RemoteClient::DAV_RESOURCE_TYPE] !== null
    && $resource[200][RemoteClient::DAV_RESOURCE_TYPE]->getValue() !== []
) {
    continue;
}

and applied the equivalent condition to the corresponding entityDelta() check.

With this change, individual CardDAV/CalDAV resources returned by Radicale are no longer incorrectly treated as collections and skipped.

Expected behaviour

DAV resources whose resourcetype property is present but empty should be treated as regular non-collection resources.

DAV Connector should import the contacts/events contained in the discovered CardDAV/CalDAV collections.

Actual behaviour

The CardDAV/CalDAV collections are discovered successfully, but their individual resources are skipped.

In my test:

  • the contacts collection was detected but initially contained 0 imported contacts;
  • after applying the getValue() !== [] check, 303 contacts were successfully imported;
  • calendar collections showed the same empty-resourcetype behaviour for individual .ics resources.

This affects both:

  • RemoteContactsService.php
  • RemoteEventsService.php

I encountered a separate issue with the initial CalDAV sync-collection synchronization, where a sync token can be stored without importing pre-existing events. I will report that separately.

Server configuration

Web server: Nginx (LinuxServer.io Nextcloud Docker image)

Database: MariaDB 11.4.8

PHP version: 8.4.16

Nextcloud version: 34.0.3.2

DAV Connector version: 1.1.0

Remote DAV server: Radicale 3.2.3.1 with radicale_storage_decsync

List of activated apps
Not included initially. Can be provided if required.
Nextcloud configuration
Not included initially. Can be provided if required.
Browser

Browser name: Firefox

Browser version: 153

Operating system: Kubuntu

Browser log
No relevant browser-side error observed. The issue occurs during server-side DAV resource processing.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in RemoteContactsService.php and RemoteEventsService.php, including the corresponding entityDelta() paths, and inspect how DAV_RESOURCE_TYPE is evaluated before resources are skipped. Verify the empty getValue() case against the existing Radicale reproduction steps. Done means empty resourcetype resources are treated as regular contacts or events and imported during Harmonize.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.