From a26a470af61bb52330bb9eed4299c4a513d4194e Mon Sep 17 00:00:00 2001 From: Chris Coutinho Date: Tue, 30 Dec 2025 23:30:01 -0600 Subject: [PATCH] fix(deck): Always preserve fields in update_card for partial updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Deck PUT API is a full replacement, not a partial update. Previously, title and description were conditionally sent, causing: - 400 errors when title not provided (it's required) - Description being cleared when not explicitly set Now all required fields (title, type, owner) and description are always included in the payload using current card values when not explicitly provided. This matches the existing pattern for type/owner. Also simplified owner extraction since DeckCard.validate_owner already ensures it's always a string. Fixes #452 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- nextcloud_mcp_server/client/deck.py | 35 +++++++++++++---------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/nextcloud_mcp_server/client/deck.py b/nextcloud_mcp_server/client/deck.py index c8c3cc2..62b6f84 100644 --- a/nextcloud_mcp_server/client/deck.py +++ b/nextcloud_mcp_server/client/deck.py @@ -285,28 +285,23 @@ class DeckClient(BaseNextcloudClient): archived: Optional[bool] = None, done: Optional[str] = None, ) -> None: - # First, get the current card to use existing values for required fields + # Deck PUT API is a full replacement - all required fields must be sent. + # Fetch current card to preserve values for fields not being updated. current_card = await self.get_card(board_id, stack_id, card_id) - json_data = {} - if title is not None: - json_data["title"] = title - if description is not None: - json_data["description"] = description - # Type is required by the API, use provided or keep current - json_data["type"] = type if type is not None else current_card.type - # Owner is required by the API, use provided or keep current - json_data["owner"] = ( - owner - if owner is not None - else ( - current_card.owner - if isinstance(current_card.owner, str) - else current_card.owner.uid - if hasattr(current_card.owner, "uid") - else current_card.owner.primaryKey - ) - ) + # Build payload with required fields always included + json_data = { + # Title is required by the API + "title": title if title is not None else current_card.title, + # Type is required by the API + "type": type if type is not None else current_card.type, + # Owner is required by the API (model validator ensures it's a string) + "owner": owner if owner is not None else current_card.owner, + # Description must be sent to preserve it (PUT clears omitted fields) + "description": description + if description is not None + else (current_card.description or ""), + } if order is not None: json_data["order"] = order if duedate is not None: