Removing a card attachment silently fails: frontend calls a non-existent OCS route (Deck 1.18.3)
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 1.4k
- Forks
- 354
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 43
Description
Describe the bug
Removing an attachment from a card does nothing. The action menu stays open, the attachment stays in the list, and no error is shown to the user.
The reason is a mismatch between the OCS route the frontend calls and the route the backend registers.
What the frontend sends (Chrome DevTools, Network tab):
DELETE /ocs/v2.php/apps/deck/api/v1.0/cards/138/attachment/file:1117?boardId=15
Result: 404 Not Found
What the backend registers (appinfo/routes.php, v1.18.3, line 165):
['name' => 'attachment_ocs#delete', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachments/{attachmentId}', 'verb' => 'DELETE'],
Two separate problems:
1. Path: the frontend uses /attachment/ (singular), the route is /attachments/ (plural).
2. Parameters: AttachmentOcsController::delete() expects a numeric attachmentId and a separate type query parameter, but the frontend passes the composite value file:1117 in the path segment.
// lib/Controller/AttachmentOcsController.php, v1.18.3
public function delete(int $cardId, int $attachmentId, string $type = 'file', ?int $boardId = null): DataResponse
The offending frontend code (src/services/AttachmentApi.js, v1.18.3):
async deleteAttachment(attachment, boardId) {
await axios({
method: 'DELETE',
url: this.ocsUrl(`/cards/${attachment.cardId}/attachment/${attachment.type}:${attachment.id}`),
params: {
boardId: boardId ?? null,
},
})
}
I verified both problems on a live instance by patching the shipped bundle:
• DELETE .../cards/165/attachment/file:1126?boardId=17 -- 404, as shipped.
• DELETE .../cards/165/attachments/file:1126?boardId=17 -- 403. The route matches, but (int) "file:1126" becomes 0, so the permission check runs against a non-existent attachment.
• DELETE .../cards/165/attachments/1126?type=file&boardId=17 -- 200, works.
Steps to reproduce
1. Open any card and switch to the Attachments tab.
2. Upload a file, or attach an existing one from Files.
3. Open the ... menu next to the attachment and click "Remove attachment".
Expected behaviour
The attachment is removed from the card. If the request fails, the user sees an error message.
Actual behaviour
Nothing happens. The menu stays open, the attachment remains, and no error is shown. The failure is only visible in the browser's network tab as a 404.
Additional notes
• restoreAttachment() looks affected as well. It sends GET .../cards/{cardId}/attachment/{type}:{id}/restore, while the route is PUT .../cards/{cardId}/attachments/{attachmentId}/restore -- wrong path and wrong verb. I did not test this.
• updateAttachment() builds the same singular path and may have the same problem.
• main looks only partly fixed. AttachmentApi.js on main now uses /attachments/ (plural), but still passes the composite ${type}:${id} in the path segment rather than a numeric id plus a type parameter. Worth checking whether that path actually resolves.
• No error handling. Even once the route is fixed, a failing request should surface a message instead of failing silently. That is what made this hard to diagnose.
• There is also a console error when opening a card with an attachment, which may or may not be connected:
TypeError: Cannot read properties of undefined (reading 'id')
at o.currentCard (deck-main.js)
Suggested fix
async deleteAttachment(attachment, boardId) {
await axios({
method: 'DELETE',
url: this.ocsUrl(`/cards/${attachment.cardId}/attachments/${attachment.id}`),
params: {
type: attachment.type,
boardId: boardId ?? null,
},
})
}
Server configuration
• Nextcloud version: 34.0.3
• Deck version: 1.18.3
• Operating system: Ubuntu 24.04.4 LTS
• Web server: Apache behind Plesk, PHP-FPM
• PHP version: 8.3
• Database: MariaDB 10.11.14
Client configuration
• Browser: Google Chrome
• Operating system: Windows
Reproduced on three independent instances, all running Nextcloud 34 with Deck 1.18.3.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/services/AttachmentApi.js, appinfo/routes.php, and lib/Controller/AttachmentOcsController.php, then reproduce the DELETE request from a card attachment. Check the delete, restore, and update routes and parameters against the registered endpoints, and verify the failure path is visible to the user. Done means attachment removal works and request failures no longer disappear silently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, php
- Domain
- api, backend, frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100