Repository navigation
fix(mcp-core): Allow string 'count' in EventsStatsResponseSchema - #1424
sentry[bot] wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d6bfafc. Configure here.
Date-typed aggregates such as max(timestamp) return ISO datetime strings from events-stats, while empty buckets are zero-filled with 0. Coercing the strings to 0 made Peak report an empty bucket. Order them by parsed time instead, and cover the zero-filled production shape.
There was a problem hiding this comment.
I checked the motivating failure and the change is justified. I pushed one correction in 6ede0d4.
Evidence: The only MCP-SERVER-GCQ event came from search_events on the errors dataset. It requested events-stats with yAxis=max(timestamp), and the ZodError reports expected number, received string only for buckets that had data (indices 6–12 and 22–24). That matches Sentry's producer: SnubaTSResultSerializer emits {"count": r.get(column, 0)} without type coercion, and zerofill writes a numeric 0 into empty buckets. So for date-typed aggregates, count is legitimately a datetime string next to numeric zeros. Widening the schema to string | number is the right-sized fix. The response is still validated as a tuple of buckets.
Correction: The formatter coerced datetime strings to 0. With the real response shape, every value was 0, so Peak pointed at the first empty bucket (Peak: 0 at …), not the latest timestamp. Datetime strings are now ordered by Date.parse and still displayed as the raw string. Numeric and additive handling is unchanged. I also updated the ISO test to include a zero-filled bucket and +00:00 offsets, and to assert the peak. Without the formatter change, that test fails with Peak: 0. I also applied oxfmt to the schema line.
Verification: mcp-core typecheck passes, and so does the full mcp-core test suite (1755 passed, 6 skipped). Repo lint passes and the touched files pass the oxfmt check. Reverting the schema change makes both new tests fail.

This PR addresses a
ZodErroroccurring when the Sentry/events-stats/API returns thecountfield as a string, particularly for non-additive aggregates likemax(timestamp).Root Cause:
The
EventsStatsResponseSchemainpackages/mcp-core/src/api-client/schema.tswas expectingcountto always be a number (z.number()), but the Sentry API can return it as a string (e.g., an epoch timestamp string or an ISO datetime string).Changes Made:
EventsStatsResponseSchemainpackages/mcp-core/src/api-client/schema.tsto define thecountfield asz.union([z.string(), z.number()]). This allows the schema to correctly parse both numeric and string representations ofcount.formatTimeSeriesResultsfunction inpackages/mcp-core/src/tools/support/search-events/formatters.ts.valueused for calculations (e.g., total, peak comparison) is now derived by coercing the rawcountto a number usingNumber(). If coercion results inNaN(e.g., for ISO datetime strings),valuedefaults to0for arithmetic safety.displayproperty was introduced for each data point. This property holds the raw string value if it's not a valid number, or the localized numeric string otherwise. This ensures that non-numeric values (like ISO datetimes) are displayed correctly to the user instead ofNaN.displayproperty.packages/mcp-core/src/tools/catalog/search-events.test.tsto specifically cover the scenario where the API returns ISO datetime strings forcount. This test asserts that the output correctly includes the datetime string and does not containNaN.These changes ensure robust handling of varying
countdata types from the Sentry API, preventing validation errors and improving the display of time series results.Fixes MCP-SERVER-GCQ
@sentry <feedback>: Autofix iterates on these changes@sentry stop iterating: Autofix stops iterating on this runThis PR was automatically generated by Sentry. You can adjust this setting at any time.