From b6fa547eb4df81a1f64390cd969b61348d90a564 Mon Sep 17 00:00:00 2001 From: Marcus van Elst Date: Mon, 13 Apr 2026 17:58:50 +0200 Subject: [PATCH] Add diagnostic logging to delete_image for DSM error 114 - Log api, method, name, tag to stderr immediately before the DSM call - Log the DSM error code on failure (visible in Claude Desktop stderr) - Include DSM error code in the return message so it appears in chat This makes the exact request params and the DSM code visible without needing debug-level logging enabled, to help diagnose why error 114 ("Invalid API call") is returned by SYNO.Docker.Image/delete. Co-Authored-By: Claude Sonnet 4.6 --- src/mcp_synology_container/modules/images.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/mcp_synology_container/modules/images.py b/src/mcp_synology_container/modules/images.py index 254f900..ee3c151 100644 --- a/src/mcp_synology_container/modules/images.py +++ b/src/mcp_synology_container/modules/images.py @@ -3,6 +3,7 @@ from __future__ import annotations import logging +import sys from datetime import UTC, datetime from typing import TYPE_CHECKING, Any @@ -242,9 +243,15 @@ def register_images(mcp: FastMCP, config: AppConfig, client: DsmClient) -> None: f"Call delete_image(image_id={image_id!r}, confirmed=True) to confirm." ) - # Perform deletion using the resolved name+tag + # Perform deletion using the resolved name+tag. + # N4S4 reference: SYNO.Docker.Image / delete, params: name, tag delete_name = repo delete_tag = img_tags[0] if img_tags else tag + sys.stderr.write( + f"[delete_image] api=SYNO.Docker.Image method=delete" + f" name={delete_name!r} tag={delete_tag!r}\n" + ) + sys.stderr.flush() try: await client.request( "SYNO.Docker.Image", @@ -252,7 +259,10 @@ def register_images(mcp: FastMCP, config: AppConfig, client: DsmClient) -> None: params={"name": delete_name, "tag": delete_tag}, ) except Exception as e: - return f"Error deleting image '{display_name}': {e}" + code = getattr(e, "code", "?") + sys.stderr.write(f"[delete_image] failed: {e} (DSM code {code})\n") + sys.stderr.flush() + return f"Error deleting '{display_name}': {e} [DSM code {code}]" return f"Deleted {display_name} — {size_str} freed."