nextcloud / nextcloud/deck

Removing a card attachment silently fails: frontend calls a non-existent OCS route (Deck 1.18.3)

Open
#8,278 1 comment 0 reactions 0 assignees View on GitHub

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

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 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.