⚠️ This issue respects the following points: ⚠️
Bug description
On desktop widths, the unified search modal renders the results of each provider as a listbox whose rows are options, and every option contains a link to the result:
UnifiedSearchModal.vue: <ul role="listbox"> with <SearchResult role="option"> for each result.
SearchResult.vue: NcListItem with :href="resourceUrl", which renders an <a> inside the <li role="option">.
axe-core 4.13 reports this as a serious violation of the rule nested-interactive (WCAG 2.1 SC 4.1.2 Name, Role, Value) for every result row, whatever app provides it. The children of an option are presentational, so assistive technology may not expose the focusable link inside it, and keyboard users can reach a control that a screen reader doesn't announce as such.
On small mobile widths the roles are dropped (isSmallMobile ? undefined : 'listbox'), so the plain list of links there passes.
Steps to reproduce
- Start the official Docker image, e.g.
nextcloud:35.0.1-apache, with any user and a file that a search finds.
- Open the unified search from the magnifier in the header on a desktop-sized window and search for that file, so that at least one result row shows.
- Run axe-core on the open modal, for example in the browser console with axe-core loaded:
await axe.run(document.querySelector('.unified-search-modal'), { runOnly: ['wcag2a', 'wcag2aa'] }).
- axe reports
nested-interactive (impact serious) on each li.result-item[role="option"].
Expected behavior
No nested interactive control inside an option. Two ways that would fit the current code:
- Keep the combobox/listbox pattern that the modal already uses (
aria-activedescendant on the input) and let the option itself open the result on Enter or click, without a focusable link inside it (for example, tabindex="-1" on the inner link or rendering it as non-interactive content); or
- drop the
listbox/option roles on desktop as well, as on small mobile, and keep the plain list of links.
Nextcloud Server version
35
Operating system
Other
PHP engine version
Other
Web server
Apache (supported)
Database engine version
SQLite
Is this bug present after an update or on a fresh install?
Fresh Nextcloud Server install
Are you using the Nextcloud Server Encryption module?
Encryption is Disabled
What user-backends are you using?
Configuration report
Official Docker image, default configuration; installed with occ maintenance:install --database=sqlite.
List of activated Apps
Default apps of the image.
Nextcloud Signing status
No errors have been found.
Nextcloud Logs
Not applicable: a front-end accessibility issue without server errors.
Additional info
Found while adding axe-core checks to the end-to-end tests of a third-party search provider (paperless_unified_search). The violation appears with every provider, Files included, and is the same on Nextcloud 33.0.9, 35.0.1 and the master build of 2026-09-30. The PHP version is the one of the official image.
Bug description
On desktop widths, the unified search modal renders the results of each provider as a
listboxwhose rows areoptions, and every option contains a link to the result:UnifiedSearchModal.vue:<ul role="listbox">with<SearchResult role="option">for each result.SearchResult.vue:NcListItemwith:href="resourceUrl", which renders an<a>inside the<li role="option">.axe-core 4.13 reports this as a serious violation of the rule
nested-interactive(WCAG 2.1 SC 4.1.2 Name, Role, Value) for every result row, whatever app provides it. The children of anoptionare presentational, so assistive technology may not expose the focusable link inside it, and keyboard users can reach a control that a screen reader doesn't announce as such.On small mobile widths the roles are dropped (
isSmallMobile ? undefined : 'listbox'), so the plain list of links there passes.Steps to reproduce
nextcloud:35.0.1-apache, with any user and a file that a search finds.await axe.run(document.querySelector('.unified-search-modal'), { runOnly: ['wcag2a', 'wcag2aa'] }).nested-interactive(impact serious) on eachli.result-item[role="option"].Expected behavior
No nested interactive control inside an
option. Two ways that would fit the current code:aria-activedescendanton the input) and let the option itself open the result on Enter or click, without a focusable link inside it (for example,tabindex="-1"on the inner link or rendering it as non-interactive content); orlistbox/optionroles on desktop as well, as on small mobile, and keep the plain list of links.Nextcloud Server version
35
Operating system
Other
PHP engine version
Other
Web server
Apache (supported)
Database engine version
SQLite
Is this bug present after an update or on a fresh install?
Fresh Nextcloud Server install
Are you using the Nextcloud Server Encryption module?
Encryption is Disabled
What user-backends are you using?
Configuration report
Official Docker image, default configuration; installed with occ maintenance:install --database=sqlite.List of activated Apps
Nextcloud Signing status
Nextcloud Logs
Additional info
Found while adding axe-core checks to the end-to-end tests of a third-party search provider (paperless_unified_search). The violation appears with every provider, Files included, and is the same on Nextcloud 33.0.9, 35.0.1 and the master build of 2026-09-30. The PHP version is the one of the official image.