From 8b9b2e0721fd2c298add1eb2d626f7ea21c3cd1e Mon Sep 17 00:00:00 2001 From: Zamil Majdy Date: Thu, 16 Apr 2026 14:49:03 +0700 Subject: [PATCH] fix(backend/copilot): warn and skip malformed tool-gap messages lacking tool_call_id In both _session_messages_to_transcript (SDK path) and _append_gap_to_builder (baseline path), silently skipping a tool message with no tool_call_id can leave the TranscriptBuilder missing a tool_result entry, which would corrupt the JSONL conversation tree used by --resume. Replace the silent drop with an explicit warning so the issue is visible in logs, making it easier to diagnose data corruption rather than discovering it as a broken --resume session later. --- .../backend/copilot/baseline/service.py | 18 +++++++++++++----- .../backend/backend/copilot/sdk/service.py | 18 +++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/autogpt_platform/backend/backend/copilot/baseline/service.py b/autogpt_platform/backend/backend/copilot/baseline/service.py index 32045ce0d6..3ebc259d1c 100644 --- a/autogpt_platform/backend/backend/copilot/baseline/service.py +++ b/autogpt_platform/backend/backend/copilot/baseline/service.py @@ -755,11 +755,19 @@ def _append_gap_to_builder( # so the builder's entry count matches the gap length. content_blocks.append({"type": "text", "text": ""}) builder.append_assistant(content_blocks=content_blocks) - elif msg.role == "tool" and msg.tool_call_id: - builder.append_tool_result( - tool_use_id=msg.tool_call_id, - content=msg.content or "", - ) + elif msg.role == "tool": + if msg.tool_call_id: + builder.append_tool_result( + tool_use_id=msg.tool_call_id, + content=msg.content or "", + ) + else: + # Malformed tool message — no tool_call_id to link to an + # assistant tool_use block. Skip to avoid an unmatched + # tool_result entry in the builder (which would confuse --resume). + logger.warning( + "[Baseline] Skipping tool gap message with no tool_call_id" + ) async def _load_prior_transcript( diff --git a/autogpt_platform/backend/backend/copilot/sdk/service.py b/autogpt_platform/backend/backend/copilot/sdk/service.py index 6db4fab304..a83c26358d 100644 --- a/autogpt_platform/backend/backend/copilot/sdk/service.py +++ b/autogpt_platform/backend/backend/copilot/sdk/service.py @@ -1228,11 +1228,19 @@ def _session_messages_to_transcript(messages: list[ChatMessage]) -> str: ) if blocks: builder.append_assistant(blocks) - elif msg.role == "tool" and msg.tool_call_id: - builder.append_tool_result( - tool_use_id=msg.tool_call_id, - content=msg.content or "", - ) + elif msg.role == "tool": + if msg.tool_call_id: + builder.append_tool_result( + tool_use_id=msg.tool_call_id, + content=msg.content or "", + ) + else: + # Malformed tool message — no tool_call_id to link to an + # assistant tool_use block. Skip to avoid an unmatched + # tool_result entry in the builder (which would confuse --resume). + logger.warning( + "[SDK] Skipping tool gap message with no tool_call_id" + ) return builder.to_jsonl()