fix(api): stop malformed time bounds reaching ClickHouse DateTime params - #627
Merged
Merged
Conversation
Two production error classes, one shape: a time string that isn't a valid
warehouse DateTime is spliced into SQL and only fails at ClickHouse.
MCP tools — normalizeTime returned unparseable input verbatim, so an
agent-supplied start_time of '2026-08-47:53' became
toDateTime('2026-08-47:53') and surfaced as an unhandled McpQueryError /
WarehouseMalformedQueryError. It now returns null; resolveTimeRange reports the
bad bound in `invalid` and substitutes the default window's bound, so st/et are
always well-formed even for a caller that doesn't check. The ten tools that
already guard `exceeded` now also return timeRangeInvalidResult, which names the
bad value and the accepted formats so the agent can retry.
v2 telemetry — parseWindow's `precision` defaulted to "millisecond", but
v2ListMetrics reads metric_catalog.Hour, a plain DateTime. Every call 500'd with
'Cannot parse string ...000 as DateTime' and a matching TYPE_MISMATCH. The
handler now asks for second precision, and `precision` is required so the next
rollup-backed handler can't inherit the unsafe default by omission.
🍁 Maple PR previewWarning Preview cleanup could not be confirmed. The Alchemy teardown outcome was Final commit |
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.
Fixes five open error issues that turn out to be two instances of one shape: a time string that isn't a valid warehouse
DateTimegets spliced into SQL and only fails at ClickHouse, as a 500 the caller can't act on.1. MCP tools passed agent garbage straight through
normalizeTimereturned unparseable input verbatim. An auto-investigation agent sentstart_time="2026-08-47:53"toexplore_attributes; that reached ClickHouse astoDateTime('2026-08-47:53')and surfaced as an unhandledMcpQueryError+WarehouseMalformedQueryError.normalizeTimenow returnsnullwhen the input isn't a timestamp.resolveTimeRangereports the bad bound in a newinvalidarray and substitutes the default window's bound for it, sost/etare always a well-formed warehouse DateTime — even for a caller that doesn't check the flag. Nothing malformed can reach the warehouse from this path any more.exceedednow also returntimeRangeInvalidResult, which names the offending value and states the accepted formats, so the agent gets a retryable tool error instead of a parse failure.invalidsuppressesexceeded: a garbage bound collapses to the default window, whose width is under any cap, and reporting "range too large" there would send the agent chasing the wrong fix.Issues:
55157217-4c27-488e-b944-136c5297c153,125b5b63-652f-4ac2-be76-79a78d2647702.
v2ListMetricssent fractional seconds to a plainDateTimecolumnparseWindow'sprecisionoption defaulted to"millisecond", but themetrics.listhandler readsmetric_catalog.Hour, which is a plainDateTime. Every call emittedtoDateTime('2026-08-24 22:54:36.000')and failed withCannot parse string … as DateTime, plus a matchingTYPE_MISMATCHon theHour <= …bound.The hazard was already documented in the
WindowPrecisiondoc comment — the default just made it opt-in. So:precision: "second".precisionis required. The eight raw-signal handlers (traces/logs/metrics onDateTime64tables) state"millisecond"explicitly, which is exactly their current behaviour — no functional change there. The next rollup-backed handler can no longer inherit the unsafe default by omission.Issues:
7010ecde-46f5-4835-8ddd-04c4122ae3f2,2669196c-efe8-435c-a48c-1005696d6675,c66b38fd-3ab9-4cdb-95ad-418f86edd336Testing
apps/apiMCP suite: 364 passedtime.test.ts: 26 passed, including the real2026-08-47:53input, both-bounds-invalid, and the invalid-beats-exceeded precedencetelemetry.http.test.ts: 11 passedNeed help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.