Skip to content

[Bug]: Call to undefined method ContactsInteraction\AddressBook::getResourceId() #63499

Description

@CraigBeckNZ

⚠️ This issue respects the following points: ⚠️

Bug description

Requesting a contact photo from the contactsinteraction address book
(z-app-generated--contactsinteraction--recent) results in an uncaught Error
and an HTTP 500.

OCA\DAV\CardDAV\ImageExportPlugin::httpGet() calls getResourceId() on the
address-book node returned by $this->server->tree->getNodeForPath():

https://github.com/nextcloud/server/blob/master/apps/dav/lib/CardDAV/ImageExportPlugin.php#L89

/** @var AddressBook $addressbook */
$addressbook = $this->server->tree->getNodeForPath($addressbookpath);

$response->setHeader('Cache-Control', 'private, max-age=3600, must-revalidate');
$response->setHeader('Etag', $node->getETag());

try {
    $file = $this->cache->get($addressbook->getResourceId(), $node->getName(), $size, $node);

getResourceId(): int is declared on OCA\DAV\DAV\Sharing\IShareable:

https://github.com/nextcloud/server/blob/master/apps/dav/lib/DAV/Sharing/IShareable.php#L51

OCA\DAV\CardDAV\AddressBook implements it. OCA\ContactsInteraction\AddressBook
does not — it is declared as:

class AddressBook extends ExternalAddressBook implements IACL

https://github.com/nextcloud/server/blob/master/apps/contactsinteraction/lib/AddressBook.php

and defines only: __construct, delete, createFile, getChild,
getChildren, childExists, getLastModified, propPatch, getProperties,
getOwner, getACL, getUid.

The /** @var AddressBook $addressbook */ annotation at the call site has no
runtime effect, and the surrounding try catches only NotFoundException, so
the Error propagates uncaught.

Both files are unchanged on master as of 23 Aug 2026.

Steps to reproduce

  1. Have at least one entry in the recently-contacted address book (this server
    has 2 rows in oc_recent_contact).
  2. Open the Contacts app in a browser and view the recently-contacted address
    book so the UI requests an avatar for one of its entries.
  3. The browser issues:
    GET /remote.php/dav/addressbooks/users/<user>/z-app-generated--contactsinteraction--recent/3?photo
  4. The request fails and the exception below is written to nextcloud.log.

The captured request came from the web UI (Chrome on Windows), not from a
CardDAV client.

Expected behavior

The photo request either returns the photo or a normal HTTP status; it does not
raise an uncaught Error.

Nextcloud Server version

34

Operating system

Debian/Ubuntu

PHP engine version

PHP 8.5

Web server

Apache (supported)

Database engine version

MariaDB

Is this bug present after an update or on a fresh install?

Upgraded to a MAJOR version (ex. 31 to 32)

Are you using the Nextcloud Server Encryption module?

None

What user-backends are you using?

  • Default user-backend (database)
  • LDAP/ Active Directory
  • SSO - SAML
  • Other

Configuration report

{
    "system": {
        "htaccess.RewriteBase": "/",
        "memcache.local": "\\OC\\Memcache\\APCu",
        "apps_paths": [
            {
                "path": "/var/www/html/apps",
                "url": "/apps",
                "writable": false
            },
            {
                "path": "/var/www/html/custom_apps",
                "url": "/custom_apps",
                "writable": true
            }
        ],
        "memcache.distributed": "\\OC\\Memcache\\Redis",
        "memcache.locking": "\\OC\\Memcache\\Redis",
        "redis": {
            "host": "***REMOVED SENSITIVE VALUE***",
            "password": "***REMOVED SENSITIVE VALUE***",
            "port": 6379
        },
        "upgrade.disable-web": true,
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": {
            "0": "192.168.x.x:8080",
            "2": "nextcloud",
            "4": "cloud.example.com"
        },
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "dbtype": "mysql",
        "version": "34.0.3.2",
        "overwrite.cli.url": "https://cloud.example.com",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbtableprefix": "oc_",
        "mysql.utf8mb4": true,
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "installed": true,
        "overwriteprotocol": "https",
        "overwritehost": "cloud.example.com",
        "trusted_proxies": "***REMOVED SENSITIVE VALUE***",
        "default_phone_region": "SG",
        "preview_max_x": 2048,
        "preview_max_y": 2048,
        "enabledPreviewProviders": [
            "OC\\Preview\\Image",
            "OC\\Preview\\HEIC",
            "OC\\Preview\\Movie",
            "OC\\Preview\\PDF",
            "OC\\Preview\\TXT",
            "OC\\Preview\\MarkDown"
        ],
        "maintenance_window_start": 18,
        "maintenance": false,
        "memories.exiftool": "/var/www/html/custom_apps/memories/bin-ext/exiftool-amd64-glibc",
        "memories.vod.path": "/var/www/html/custom_apps/memories/bin-ext/go-vod-amd64",
        "loglevel": 2,
        "skeletondirectory": "",
        "mail_smtpmode": "smtp",
        "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpport": "587",
        "mail_smtpsecure": "",
        "mail_smtpauth": false,
        "mail_smtpauthtype": "LOGIN",
        "mail_smtpname": "***REMOVED SENSITIVE VALUE***",
        "mail_from_address": "***REMOVED SENSITIVE VALUE***",
        "mail_domain": "***REMOVED SENSITIVE VALUE***",
        "mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
        "serverid": 0,
        "memories.db.triggers.fcu": true,
        "preview_ffmpeg_path": "/usr/local/bin/ffmpeg"
    }
}

List of activated Apps

Enabled:
  - activity: 7.0.0
  - appstore: 1.0.0
  - bruteforcesettings: 7.0.0
  - calendar: 6.5.4
  - circles: 34.0.0
  - cloud_federation_api: 1.18.0
  - comments: 1.24.0
  - contacts: 8.7.6
  - contactsinteraction: 1.15.0
  - dashboard: 7.14.0
  - dav: 1.40.0
  - federatedfilesharing: 1.24.0
  - federation: 1.24.0
  - files: 2.6.0
  - files_downloadlimit: 5.2.0
  - files_lock: 34.0.1
  - files_pdfviewer: 7.0.0-dev.0
  - files_reminders: 1.7.0
  - files_sharing: 1.26.0
  - files_trashbin: 1.24.0
  - files_versions: 1.27.0
  - firstrunwizard: 7.0.0-dev.0
  - logreader: 7.0.0
  - lookup_server_connector: 1.22.0
  - memories: 8.1.0
  - nextcloud_announcements: 6.0.0
  - notes: 6.0.2
  - notifications: 7.0.0-dev.1
  - oauth2: 1.22.0
  - office: 1.0.0
  - password_policy: 6.0.0-dev.0
  - photos: 7.0.0
  - previewgenerator: 5.14.0
  - privacy: 6.0.0-dev.1
  - profile: 1.3.0
  - provisioning_api: 1.24.0
  - recommendations: 7.0.0
  - related_resources: 5.0.0-dev.0
  - serverinfo: 6.0.0
  - settings: 1.17.0
  - sharebymail: 1.24.0
  - support: 6.0.0
  - survey_client: 6.0.0-dev.0
  - systemtags: 1.24.0
  - text: 8.0.0
  - theming: 2.9.0
  - twofactor_backupcodes: 1.23.0
  - twofactor_totp: 16.0.0
  - updatenotification: 1.24.0
  - user_status: 1.14.0
  - viewer: 7.0.0-dev.0
  - weather_status: 1.14.0
  - webhook_listeners: 1.6.0
  - workflowengine: 2.16.0
Disabled:
  - admin_audit: 1.24.0
  - app_api: 34.0.0 (installed 32.0.0)
  - encryption: 2.22.0
  - files_external: 1.26.0
  - suspicious_login: 12.0.0-dev.0
  - twofactor_nextcloud_notification: 8.0.0
  - user_ldap: 1.25.0

Nextcloud Signing status

No errors have been found.

Nextcloud Logs

{
    "reqId": "S2ZOcRVbh1vlkkV5cIUS",
    "level": 3,
    "time": "2026-08-20T10:39:42+00:00",
    "remoteAddr": "192.168.x.x",
    "user": "<user>",
    "app": "webdav",
    "method": "GET",
    "url": "/remote.php/dav/addressbooks/users/<user>/z-app-generated--contactsinteraction--recent/3?photo",
    "scriptName": "/remote.php",
    "message": "Call to undefined method OCA\\ContactsInteraction\\AddressBook::getResourceId()",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36",
    "version": "34.0.3.2",
    "exception": {
        "Exception": "Error",
        "Message": "Call to undefined method OCA\\ContactsInteraction\\AddressBook::getResourceId()",
        "Code": 0,
        "Trace": [
            {
                "file": "/var/www/html/3rdparty/sabre/event/lib/WildcardEmitterTrait.php",
                "line": 89,
                "function": "httpGet",
                "class": "OCA\\DAV\\CardDAV\\ImageExportPlugin",
                "type": "->",
                "args": [
                    {
                        "__class__": "Sabre\\HTTP\\Request"
                    },
                    {
                        "__class__": "Sabre\\HTTP\\Response"
                    }
                ]
            },
            {
                "file": "/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php",
                "line": 472,
                "function": "emit",
                "class": "Sabre\\DAV\\Server",
                "type": "->",
                "args": [
                    "method:GET",
                    [
                        {
                            "__class__": "Sabre\\HTTP\\Request"
                        },
                        {
                            "__class__": "Sabre\\HTTP\\Response"
                        }
                    ]
                ]
            },
            {
                "file": "/var/www/html/apps/dav/lib/Connector/Sabre/Server.php",
                "line": 215,
                "function": "invokeMethod",
                "class": "Sabre\\DAV\\Server",
                "type": "->",
                "args": [
                    {
                        "__class__": "Sabre\\HTTP\\Request"
                    },
                    {
                        "__class__": "Sabre\\HTTP\\Response"
                    }
                ]
            },
            {
                "file": "/var/www/html/apps/dav/lib/Server.php",
                "line": 433,
                "function": "start",
                "class": "OCA\\DAV\\Connector\\Sabre\\Server",
                "type": "->",
                "args": []
            },
            {
                "file": "/var/www/html/apps/dav/appinfo/v2/remote.php",
                "line": 25,
                "function": "exec",
                "class": "OCA\\DAV\\Server",
                "type": "->",
                "args": []
            },
            {
                "file": "/var/www/html/remote.php",
                "line": 152,
                "args": [
                    "/var/www/html/apps/dav/appinfo/v2/remote.php"
                ],
                "function": "require_once"
            }
        ],
        "File": "/var/www/html/apps/dav/lib/CardDAV/ImageExportPlugin.php",
        "Line": 89,
        "message": "Call to undefined method OCA\\ContactsInteraction\\AddressBook::getResourceId()",
        "exception": "{\"class\":\"Error\",\"message\":\"Call to undefined method OCA\\ContactsInteraction\\AddressBook::getResourceId()\",\"code\":0,\"file\":\"/var/www/html/apps/dav/lib/CardDAV/ImageExportPlugin.php:89\",\"trace\":\"#0 /var/www/html/3rdparty/sabre/event/lib/WildcardEmitterTrait.php(89): OCA\\DAV\\CardDAV\\ImageExportPlugin->httpGet(Object(Sabre\\HTTP\\Request), Object(Sabre\\HTTP\\Response))\\n#1 /var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php(472): Sabre\\DAV\\Server->emit('method:GET', Array)\\n#2 /var/www/html/apps/dav/lib/Connector/Sabre/Server.php(215): Sabre\\DAV\\Server->invokeMethod(Object(Sabre\\HTTP\\Request), Object(Sabre\\HTTP\\Response))\\n#3 /var/www/html/apps/dav/lib/Server.php(433): OCA\\DAV\\Connector\\Sabre\\Server->start()\\n#4 /var/www/html/apps/dav/appinfo/v2/remote.php(25): OCA\\DAV\\Server->exec()\\n#5 /var/www/html/remote.php(152): require_once('/var/www/html/a...')\\n#6 {main}\"}",
        "CustomMessage": "Call to undefined method OCA\\ContactsInteraction\\AddressBook::getResourceId()"
    }
}

Additional info

Present on master as well as 34. Both files checked on 23 Aug 2026:

No app update is available. occ update:check reports "Everything up to
date"; contactsinteraction 1.15.0 is what ships with 34.0.3.2.

Not limited to this app. ImageExportPlugin obtains the address book via
$this->server->tree->getNodeForPath() and does not narrow the result to
OCA\DAV\CardDAV\AddressBook, which is the class implementing IShareable.
Any node at an address-book path that does not implement IShareable reaches
the same call. nextcloud/ldap_contacts_backend also extends
ExternalAddressBook:
https://github.com/nextcloud/ldap_contacts_backend/blob/main/lib/Service/AddressBook.php
I have not tested that backend, so I cannot confirm it is affected.

Reproduction context. The captured request came from the Contacts web UI in
Chrome 151 on Windows, not from a CardDAV client. The address book held 2 rows
in oc_recent_contact at the time.

Browser console output was not captured — the failure was found in
nextcloud.log after the fact, not while watching a browser session, so I have
no client-side errors to attach. I can reproduce and capture them if that would
help.

Environment notes. Instance was upgraded 33 → 34, not a fresh install. It
runs behind Nginx Proxy Manager; trusted_proxies is set to the Docker bridge
range and real client IPs are recorded correctly, as the remoteAddr in the log
entry shows. Memcache is APCu local with Redis distributed/locking.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status
    To triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions