Classify Kernel API failures on tool errors - #133
Open
masnwilliams wants to merge 1 commit into
Open
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Every failed MCP tool call currently records
$mcp_error_type = "Error", so a stale session id, an org hitting its concurrency limit, and a fault on our side are indistinguishable in analytics. This names them.toolErrorResponsebecomesthrowToolError, which throws instead of returning anisErrorresult. The thrown error'snamecarries the Kernel API status —KernelApiError404,KernelApiError429,KernelApiError502— or the SDK error class for transport failures (APIConnectionTimeoutError).Why this works
The analytics SDK reads the error category from a thrown error's
name. A returnedisErrorresult has no error object, so it coerces from the result text and always lands as a genericError. That's why the existing data has exactly one error type.Because
throwToolErroris the single funnel for caught API errors, the split falls out with no per-call-site logic:KernelApiError<status>— the Kernel API rejected the request.Error— the tool itself rejected the call (missingsession_id, conflicting arguments, invalid config), which never reaches the API.Agents see no change
The MCP SDK converts a thrown error back into the same
isErrortext result, and the message string is byte-identical to what the helper produced before. Verified against the real API:manage_browsersgetwith an unknown session id →Error in manage_browsers (get): 404 browser session '...' not found,isError: truemanage_browsersgetwith no session id →Error: session_id is required for get action.,isError: truePrivacy
Status codes only. No message, parameters, or response are captured — confirmed on the captured events — and no
$exceptionevents are emitted.$mcp_error_typeis already on the send allow-list, so nothing new is added to what leaves the server.Verification
Ran the route locally against the production API and checked the captured events:
$mcp_error_typeKernelApiError404session_idErrortsc --noEmitandprettier --checkpass on every touched file.Follow-up, deliberately not here
The generic
Errorbucket still mixes several kinds of tool-side rejection (missing argument vs conflicting arguments vs invalid config). Naming those too is mechanical but touches ~95 call sites, so it belongs in its own change if the split turns out to be worth it.Note
Low Risk
Mechanical error-handling refactor across MCP tools; agent-visible behavior is intended to stay the same, with analytics-only classification added.
Overview
MCP tool handlers now throw classified errors on Kernel API failures instead of returning
isErrorresults, so analytics can record distinct$mcp_error_typevalues (e.g.KernelApiError404,KernelApiError429) instead of a genericError.toolErrorResponseis replaced bythrowToolError, which throws aToolCallErrorwhosenamecomes from the SDKAPIErrorHTTP status (KernelApiError{status}) or the underlying error class for non-API failures. The user-facing message is unchanged; the MCP SDK still surfaces the sameisErrortext to agents.All MCP tool
catchblocks that handled API errors are updated to callthrowToolError. Input validation paths stillreturn errorResponse(...)and remain in the genericErrorbucket.Reviewed by Cursor Bugbot for commit b9aa34d. Bugbot is set up for automated code reviews on this repo. Configure here.