Skip to content

fix(sensor): record the message of a failed Copilot tool's error - #214

Open
rudycelekli wants to merge 1 commit into
uber:mainfrom
rudycelekli:fix/sensor-copilot-tool-error-message
Open

rudycelekli wants to merge 1 commit into
uber:mainfrom
rudycelekli:fix/sensor-copilot-tool-error-message

Conversation

@rudycelekli

@rudycelekli rudycelekli commented Oct 19, 2026 •

Copy link
Copy Markdown

What type of PR is this? (check all applicable)

  • Refactor
  • Feature
  • Bug Fix
  • Optimization
  • Documentation Update

Related issue: N/A (found by reading the code; reproduced on main at 6b33dff)

What changed?
New _normalize_tool_error returns the (truncated) message when the error is an object with a non-empty string message; anything else goes through the old path, so the existing string-error test still passes.

Why?
Copilot's schema defines tool.execution_complete error as ToolExecutionCompleteError {"message": str, "code"?: str} (github/copilot-sdk session_events.py). CopilotParser passes it to _normalize_tool_result (Sensor/adr_sensor/parsers/copilot_parser.py:302), which only knows result objects (detailedContent/content) and falls back to json.dumps, so a rejected tool gets error '{"message": "The user rejected this tool call.", "code": "denied"}'.

How did you test it?

  • Reproduction: new TestCopilotParser::test_tool_failure_uses_message_of_error_object. main parser: FAILED ('{"message": ...e": "denied"}' == 'The user rej...is tool call.'); branch: passed.
  • Test suite: Sensor pytest tests/ -q (py3.14) 609 passed; Python 3.9.6 parser test files 245 passed.
  • Not tested: real Copilot logs (none locally). Low-to-moderate impact: the message was already inside the JSON blob; the fix makes the field the plain message other parsers emit. The error code is dropped (still not exported elsewhere).

Potential risks
The change only affects the input described above; other paths go through the same code as before, and the component's existing tests pass.

Copilot's session events record a failed tool's error as an object,
{"message": ..., "code": ...}. The parser serialized that object, so
ToolUsage.error held a JSON blob such as
'{"message": "The user rejected this tool call.", "code": "denied"}'.
It now uses the message; plain string errors are handled as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants