Skip to content

analytics: a valid preset plus compareTo is refused 400 DATASET_INVALID "invalid date in dateRange" — dataset-executor.runCompare still uses the [range, range] fallback #17015 removed everywhere else #17973

Description

@os-bill

A valid analytics preset combined with compareTo is refused with a wrong-shaped 400, instead of being lowered to a window and shifted.

Filed by the domain:spec execution seat, session session_01MkQhmuuJAVDjmeWNixwDDH, 2026-09-13T08:53Z, out of the at-tier post-hoc contract review of merged PR #17015 (record: that PR's comment, Served-tier: 102/102 claude-fable-5-1). ⛔ No domain:* or priority:* applied — routing and grading are triage's.

The defect

packages/services/service-analytics/src/dataset-executor.ts:1316-1318 (runCompare), read on origin/main 2c87a48f: the string arm of dateRange is spelled as [td.dateRange, td.dateRange] — the same degenerate [range, range] fallback that PR #17015 removed from every other analytics face. parseUTC (:477-487) then throws:

DATASET_INVALID  "invalid date in dateRange: \"last_30_days\""

last_30_days — a declared, honoured preset, one of the thirteen the closed vocabulary names — is reported to the caller as an invalid date. It is not invalid; it is a preset this face never learned to lower.

Why it is worth a card rather than a note

The diagnostic sends the author to the wrong repair. Someone reading "invalid date in dateRange" checks their date, finds last_30_days is exactly what the docs and the schema tell them to write, and has nowhere to go. The refusal is not merely unhelpful — it is false, and a false diagnostic on a valid input costs more than a missing feature.

It is also precisely the class PR #17015 was dispatched to close. That PR aligned four faces to the closed vocabulary; this face was not in the kit, so nothing measured it and nothing noticed. Its own conformance kit (analyticsDateRangeConformanceFindings) exists specifically to make this population enumerable — the repair is to register this face in it, so the next face that forgets is caught by a test instead of by a customer.

The repair

Route the string arm through resolveAnalyticsDateRangeString (packages/core/src/utils/analytics-date-range.ts, exported by #17015 for exactly this), then apply the comparison shift to the resolved window. Register runCompare as a face in the conformance kit in the same change.

Provenance and honesty about the reading

⚠️ This was flagged as finding F2 by an earlier review round on PR #17015 and never filed. That is why it is here: an acceptance note with no named carrier is not a disposition.

⚠️ 待证伪前提 — this is a source reading, not an execution. The reviewer read runCompare and parseUTC on origin/main and did not run the path. Whoever takes this should reproduce it first (a preset plus compareTo through the dataset executor); if it does not reproduce, the card is wrong and should be closed with the reading that disproves it, ⛔ not quietly narrowed.


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions