Board in trash breaks file listing (PROPFIND 500) for users with a card attachment shared/mounted
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
调研方向
从 BoardMapper::findBoardIds() 以及报告中提到的 _getSharedWith()、applyBoardPermission() 和 PermissionService::checkPermission() 路径开始。跟踪软删除的 board 如何到达 files mount 设置,然后使用已挂载的卡片附件重现 PROPFIND 失败。完成标准是:来自已移入回收站的 board 的共享不会被挂载,并且文件列表在回收站保留期间不再返回 HTTP 500。
由索引模型根据 Issue 内容生成。
描述
Describe the bug
When a board is deleted, Deck only soft-deletes it (deck_boards.deleted_at is set) and the row stays until DeleteCron hard-deletes it after trashRetentionHours. During that window, every user who has a file attachment of a card on that board mounted in their file tree gets an uncaught DoesNotExistException on every file listing.
The exception escapes into the files mount setup, so it does not just break Deck. It breaks PROPFIND on the user's files root, which means the desktop client can no longer sync and the Files app fails to list.
The error stops on its own once DeleteCron removes the board row, which makes it look transient, but it lasts for the whole trash retention period.
To Reproduce
- As user A, attach a file from Files to a card ("share file with card", creates an
oc_sharerow withshare_type = 12andshare_with = <card id>). - Share the board with user B, so the attachment is mounted for B.
- As user A, delete the board. Do not empty the trash.
- As user A or B, run a PROPFIND on the files root (open Files, or let the desktop client sync).
Result: HTTP 500, and the log entry below on every request.
Expected behavior
Shares belonging to a board in the trash should not be resolved into mounts, and a trashed board must never cause an uncaught exception in the files mount setup.
Root cause
(line numbers from master, 4.0.0-dev.2)
BoardMapper::findBoardIds()(lib/Db/BoardMapper.php:81) has nodeleted_at = 0filter, so boards in the trash stay in the list.DeckShareProvider::_getSharedWith()(lib/Sharing/DeckShareProvider.php:826) filters onlydc.deleted_at = 0, which is the card. A card on a trashed board still hasdeleted_at = 0, so its share is returned.DeckShareProvider::applyBoardPermission()(lib/Sharing/DeckShareProvider.php:678) callscheckPermission(..., $allowDeletedCard = true)while$allowDeletedBoardstaysfalse.PermissionService::checkPermission()(lib/Service/PermissionService.php:157) passes thatfalsetogetPermissions()->getBoard()->BoardMapper::find(..., $allowDeleted = false), which builds thedeleted_at = 0query and throwsDoesNotExistException.applyBoardPermission()only catchesNoPermissionException, so the exception propagates throughOC\Share20\Manager::getSharedWith()andOCA\Files_Sharing\MountProviderintoOC\Files\SetupManager, aborting the request.
Possible fix
Any of these, the first two look safer because a trashed board's shares should not be mounted at all:
- add
deleted_at = 0toBoardMapper::findBoardIds() - add
db.deleted_at = 0to the_getSharedWith()query - pass
$allowDeletedBoard = trueinapplyBoardPermission()and additionally catchDoesNotExistExceptionthere
Server details
Operating system: Rocky Linux 9
Web server: Apache/2.4.62
Database: MariaDB-server 11.4.12
PHP version: PHP 8.5.9
Nextcloud version: 34.0.2.1
Where did you install Nextcloud from: wget https://download.nextcloud.com/server/releases/{{ nextcloud__version }}.tar.bz2
Signing status:
No errors have been found.
List of activated apps:
Enabled:
- admin_audit: 1.24.0
- appstore: 1.0.0
- bruteforcesettings: 7.0.0
- calendar: 6.5.2
- calendar_resource_management: 0.12.1
- cloud_federation_api: 1.18.0
- comments: 1.24.0
- contacts: 8.7.5
- contactsinteraction: 1.15.0
- dashboard: 7.14.0
- dav: 1.39.0
- deck: 1.18.3
- drawio: 4.3.5
- federatedfilesharing: 1.24.0
- files: 2.6.0
- files_downloadlimit: 5.2.0
- files_external: 1.26.0
- files_lock: 34.0.1
- files_pdfviewer: 7.0.0-dev.0
- files_sharing: 1.26.0
- files_trashbin: 1.24.0
- files_versions: 1.27.0
- forms: 5.3.5
- impersonate: 5.0.0
- logreader: 7.0.0
- lookup_server_connector: 1.22.0
- mail: 5.10.11
- notes: 6.0.1
- notifications: 7.0.0-dev.1
- notify_push: 1.3.5
- oauth2: 1.22.0
- office: 1.0.0
- password_policy: 6.0.0-dev.0
- polls: 9.1.4
- privacy: 6.0.0-dev.1
- profile: 1.3.0
- provisioning_api: 1.24.0
- related_resources: 5.0.0-dev.0
- richdocuments: 11.1.0
- serverinfo: 6.0.0
- settings: 1.17.0
- sharebymail: 1.24.0
- spreed: 24.0.3
- systemtags: 1.24.0
- tasks: 0.18.1
- text: 8.0.0
- theming: 2.9.0
- twofactor_admin: 4.12.0
- twofactor_backupcodes: 1.23.0
- twofactor_email: 3.4.1
- twofactor_totp: 16.0.0
- updatenotification: 1.24.0
- viewer: 7.0.0-dev.0
- webhook_listeners: 1.6.0
- whiteboard: 1.5.9
- workflowengine: 2.16.0
Disabled:
- activity: 7.0.0 (installed 7.0.0)
- announcementcenter: 7.5.0 (installed 7.5.0)
- app_api: 34.0.0 (installed 32.0.0)
- circles: 34.0.0 (installed 31.0.0)
- encryption: 2.22.0
- federation: 1.24.0 (installed 1.21.0)
- files_reminders: 1.7.0 (installed 1.4.0)
- firstrunwizard: 7.0.0-dev.0 (installed 4.0.0)
- nextcloud_announcements: 6.0.0 (installed 3.0.0)
- photos: 7.0.0 (installed 4.0.0)
- recommendations: 7.0.0 (installed 4.0.0)
- support: 6.0.0 (installed 3.0.0)
- survey_client: 6.0.0-dev.0 (installed 3.0.0)
- suspicious_login: 12.0.0-dev.0 (installed 11.0.0-dev.0)
- testing: 1.23.0
- twofactor_nextcloud_notification: 8.0.0
- user_ldap: 1.25.0
- user_status: 1.14.0 (installed 1.12.0)
- weather_status: 1.14.0 (installed 1.11.0)
Are you using an external user-backend, if yes which one: no
Logs
Nextcloud log (data/nextcloud.log)
Repeating on every PROPFIND (user, request IDs and remote address redacted):
{"reqId":"REDACTED","level":3,"time":"2026-08-10T22:06:35+02:00","remoteAddr":"REDACTED","user":"REDACTED","app":"webdav","method":"PROPFIND","url":"/remote.php/dav/files/REDACTED/","scriptName":"/remote.php","message":"Did expect one result but found none when executing: query \"SELECT * FROM `*PREFIX*deck_boards` WHERE (`id` = :dcValue2) AND (`deleted_at` = :dcValue1) ORDER BY `id` ASC\"; ","userAgent":"Mozilla/5.0 (Macintosh) mirall/34.0.1 (Nextcloud, macos-25.5.0)","version":"34.0.2.1","exception":{"Exception":"OCP\\AppFramework\\Db\\DoesNotExistException","Message":"Did expect one result but found none when executing: query \"SELECT * FROM `*PREFIX*deck_boards` WHERE (`id` = :dcValue2) AND (`deleted_at` = :dcValue1) ORDER BY `id` ASC\"; "}}
- 主要语言
- JavaScript
- 星标
- 1.4k
- 派生
- 360
- 平均合并
- 1 天 22 小时
- 30 天内合并 PR
- 101
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
nextcloud/deck 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 1 天内回复
-
CSV export leaves trailing commas in tags and assigned-user fields可能已有人在做 @Kumar-s75 于 42 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 88/100
维护者通常 1 天内回复
-
Board clone API failure is treated as a successful board response可能已有人在做 @Kumar-s75 于 42 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 88/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
1. to develop bug
难度 2/5 1-3 小时 新手友好度 78/100
nextcloud/deck#8146 · 2 条评论 · 2 个 reaction ·
维护者通常 1 天内回复
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 82/100
AOSSIE-Org/BabyNest#268 ·
维护者通常 1 天内回复
-
Add: DG:TV未关闭channels:add check:passed
难度 2/5 1-3 小时 新手友好度 68/100
-
[Bug Report][3.13.7] VDataTable with select-strategy="single" shows select-all checkbox in mobile mode可能已有人在做 @lazerg 今天认领。 未关闭S: triage
难度 2/5 1-3 小时 新手友好度 65/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
-
external-plugin ready-for-review third party
难度 2/5 1-3 小时 新手友好度 63/100
github/awesome-copilot#5259 · 1 条评论 ·
维护者通常 1 天内回复