Skip to content

Commit d03ded5

Browse files
authored
azurebackup: Fix KQL classification order and update bug tracker in telemetry skill (#2659)
* azurebackup: Fix KQL classification order and update bug tracker in telemetry skill The KQL case() expression in kql-queries.md checked StatusCode 400-499 before exception type, which masked MCP tool bugs (ArgumentNullException, ArgumentException, FormatException) as Customer errors when HandleException mapped them to HTTP 400. This caused the weekly telemetry report to undercount MCP bugs by ~33x (1 vs 34 in the May 11-17 report). Changes: - kql-queries.md: Reorder case() in queries 1, 2, and 4 to check MCP bug exception types (FormatException, ArgumentNullException, ArgumentException, InvalidOperationException) BEFORE StatusCode 400-499 - SKILL.md: Update decision tree to match the classification table (check exception type before status code), add explanatory note about HandleException mapping ArgumentNullException to HTTP 400 - SKILL.md: Update known bug table with current state: - BUG-1: Mark #2518 as partial fix, add #2621 as defense-in-depth - BUG-3: Mark #2518 as partial, add #2621 relaxed regex - Add NEW-2 (job_get FormatException in DPP SDK, azure-sdk-for-net#59306) - Update notes about incomplete #2518 fixes confirmed on beta.8/beta.9 * Address PR review: fix decision tree nesting and use 'pending' for unreleased versions - Add missing NO branch under StatusCode check in decision tree for proper nesting (Copilot review comment 1) - Replace 'beta.11 (pending)' with 'pending' in bug tracker Release column to avoid presuming version number (Copilot review comment 2)
1 parent bcd71e2 commit d03ded5

2 files changed

Lines changed: 24 additions & 15 deletions

File tree

tools/Azure.Mcp.Tools.AzureBackup/skills/azurebackup-telemetry-report/SKILL.md

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -152,20 +152,26 @@ For the Outlook version, apply these rules:
152152

153153
## Error Classification Decision Tree
154154

155+
> **Important:** MCP bug exception types must be checked **before** StatusCode.
156+
> The `HandleException` base class maps `ArgumentNullException` (inherits `ArgumentException`)
157+
> to HTTP 400, which would incorrectly classify MCP bugs as "Customer" errors if StatusCode
158+
> is checked first.
159+
155160
```
156161
Is success == true?
157162
└─ YES → "Success"
158163
└─ NO →
159-
Is StatusCode 400/403/404?
160-
└─ YES → "Customer (4xx)"
164+
Is ExceptionType FormatException / ArgumentNullException / ArgumentException / InvalidOperationException?
165+
└─ YES → "MCP Tool Bug"
161166
└─ NO →
162-
Is ExceptionType Azure.RequestFailedException with 5xx?
163-
└─ YES → "Azure Service"
164-
Is ExceptionType System.AggregateException?
165-
└─ YES → "Azure Service"
166-
Is ExceptionType FormatException / ArgumentNullException / ArgumentException / InvalidOperationException?
167-
└─ YES → "MCP Tool Bug"
168-
Otherwise → "Unknown" (investigate)
167+
Is StatusCode 400/403/404?
168+
└─ YES → "Customer (4xx)"
169+
└─ NO →
170+
Is ExceptionType Azure.RequestFailedException with 5xx?
171+
└─ YES → "Azure Service"
172+
Is ExceptionType System.AggregateException?
173+
└─ YES → "Azure Service"
174+
Otherwise → "Unknown" (investigate)
169175
```
170176

171177
## Known Bug IDs
@@ -174,18 +180,21 @@ These are the bugs triaged from the original telemetry analysis (April 2026):
174180

175181
| Bug | Tool | Description | Fix PR | Release |
176182
|-----|------|-------------|--------|---------|
177-
| BUG-1 | backup_status | ArgumentNullException on null ResourceType | #2518 (code included, not in PR title) | beta.7 |
183+
| BUG-1 | backup_status, protecteditem_get | ArgumentNullException on null ResourceType in MapArmResourceTypeToBackupDataSourceType | #2518 (partial), #2621 (defense-in-depth) | beta.7 (partial), pending |
178184
| BUG-2 | protecteditem_protect | VM pre-discovery loop timeout | #2470 | beta.6 |
179-
| BUG-3 | protectableitem_list | Workload normalization ArgumentException | #2518 | beta.7 |
185+
| BUG-3 | protectableitem_list, find-unprotected | Workload normalization ArgumentException in ValidateAndParseResourceTypeFilter | #2518 (partial), #2621 (relaxed regex) | beta.7 (partial), pending |
180186
| BUG-4 | soft-delete | Deprecated BackupResourceVaultConfig API | #2518 | beta.7 |
181187
| BUG-5 | enable-crr | Deprecated BackupResourceConfig API | #2518 | beta.7 |
182188
| BUG-6 | vault_get | FormatException on subscription name (non-GUID) | #2518 | beta.7 |
183189
| BUG-7 | protecteditem_protect | DPP vault missing managed identity | #2470 | beta.6 |
184190
| BUG-8 | recoverypoint_get | Null container in resolution | #2518 | beta.7 |
185191
| NEW-1 | vault_get | AggregateException — pre-existing auth race (Azure Service, not MCP bug) | Not filed ||
192+
| NEW-2 | job_get | FormatException in DPP SDK — XmlConvert.ToTimeSpan fails during DataProtectionBackupJobProperties.Deserialize (Azure SDK bug, not MCP code) | #2621 (workaround catch), [azure-sdk#59306](https://github.com/Azure/azure-sdk-for-net/issues/59306) (upstream) | pending |
186193

187194
> **Note:** PR #2518 title says "Fix 5 telemetry-triaged bugs (BUG-3,4,5,6,8)" but the
188-
> actual merged code also includes the BUG-1 fix. Always verify the diff, not just the title.
195+
> actual merged code also includes the BUG-1 fix. However, the #2518 fixes for BUG-1 and
196+
> BUG-3 were **incomplete** — confirmed by telemetry on beta.8/beta.9. PR #2621 adds
197+
> defense-in-depth fixes for both. Always verify the diff, not just the title.
189198
190199
When new errors appear, assign the next sequential ID (NEW-2, NEW-3, etc.) and add to this table.
191200

tools/Azure.Mcp.Tools.AzureBackup/skills/azurebackup-telemetry-report/references/kql-queries.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ getAzureMcpEvents_ToolCalls(ago(7d), now())
2424
| extend StatusCode = toint(extract(@"StatusCode.*?(\d+)", 1, ExMsg))
2525
| extend ErrorCategory = case(
2626
success == true, "Success",
27+
ExType in ("System.FormatException", "System.ArgumentNullException", "System.ArgumentException", "System.InvalidOperationException"), "McpToolBug",
2728
StatusCode >= 400 and StatusCode < 500, "Customer",
2829
ExType == "System.Collections.Generic.KeyNotFoundException", "Customer",
2930
ExType == "Azure.RequestFailedException" and StatusCode >= 500, "AzureService",
3031
ExType == "System.AggregateException", "AzureService",
31-
ExType in ("System.FormatException", "System.ArgumentNullException", "System.ArgumentException", "System.InvalidOperationException"), "McpToolBug",
3232
"Unknown")
3333
| summarize
3434
Total = count(),
@@ -62,11 +62,11 @@ getAzureMcpEvents_ToolCalls(TwoWeeksAgo, now())
6262
| extend StatusCode = toint(extract(@"StatusCode.*?(\d+)", 1, ExMsg))
6363
| extend ErrorCategory = case(
6464
success == true, "Success",
65+
ExType in ("System.FormatException", "System.ArgumentNullException", "System.ArgumentException", "System.InvalidOperationException"), "McpToolBug",
6566
StatusCode >= 400 and StatusCode < 500, "Customer",
6667
ExType == "System.Collections.Generic.KeyNotFoundException", "Customer",
6768
ExType == "Azure.RequestFailedException" and StatusCode >= 500, "AzureService",
6869
ExType == "System.AggregateException", "AzureService",
69-
ExType in ("System.FormatException", "System.ArgumentNullException", "System.ArgumentException", "System.InvalidOperationException"), "McpToolBug",
7070
"Unknown")
7171
| summarize
7272
Total = count(),
@@ -111,11 +111,11 @@ getAzureMcpEvents_ToolCalls(ago(7d), now())
111111
ExType = tostring(customDimensions["exception.type"])
112112
| extend StatusCode = toint(extract(@"StatusCode.*?(\d+)", 1, ExMsg))
113113
| extend ErrorCategory = case(
114+
ExType in ("System.FormatException", "System.ArgumentNullException", "System.ArgumentException", "System.InvalidOperationException"), "McpToolBug",
114115
StatusCode >= 400 and StatusCode < 500, "Customer",
115116
ExType == "System.Collections.Generic.KeyNotFoundException", "Customer",
116117
ExType == "Azure.RequestFailedException" and StatusCode >= 500, "AzureService",
117118
ExType == "System.AggregateException", "AzureService",
118-
ExType in ("System.FormatException", "System.ArgumentNullException", "System.ArgumentException", "System.InvalidOperationException"), "McpToolBug",
119119
"Unknown")
120120
| summarize Count = count()
121121
by ToolName, StatusCode, ErrorCategory, ExType

0 commit comments

Comments
 (0)