Skip to content

fix(frontend): analytics range bounds keep their UTC designator - #5923

Merged
mmabrouk merged 1 commit into
release/v0.112.0from
fix/observability-utc-range
Aug 11, 2026
Merged

mmabrouk merged 1 commit into
release/v0.112.0from
fix/observability-utc-range

Conversation

@ardaerzin

Copy link
Copy Markdown
Contributor

Context

Observability dashboards misbehave for anyone whose machine is not on UTC. West of UTC they fail outright: pick the 30 minutes range in New York and the query asks for a window that ends before it starts, so fetchDashboardAnalytics throws "endTime must be greater than or equal to startTime" and no chart renders. East of UTC there is no error at all, just a silently wider window than the one you picked.

The range bounds lose their UTC designator on the way out. toISOString().split(".")[0] trims the milliseconds and the trailing Z, and the value is read a second time with dayjs(startTime), which treats a stamp with no designator as local time. The offset is then applied twice.

Changes

utcRangeStamp() joins the other helpers in dateTimeHelper and keeps the designator. It replaces the hand-rolled truncation at every site that feeds a query: the preset branch and both custom range bounds in Sort.tsx, plus the two dashboard defaults in newObservability/atoms/controls.ts and observability/dashboard.ts. The "all time" literal gets the same treatment.

Before:

2026-08-11T05:24:59

After:

2026-08-11T05:24:59Z

Nothing changes on the wire. The API parses both forms with datetime.fromisoformat, and parse_windowing stamps a naive datetime as UTC, so the server already resolved these to the same instant. The defect was entirely client side, in the second parse.

Tests

Measured a 30 minute preset in four zones, comparing the duration the client computes and whether the window end lands before its start:

Timezone Before After
UTC 30 min 30 min
Europe/Istanbul (+3) 210 min 30 min
America/New_York (-4) -209 min, query throws 30 min
America/Los_Angeles (-7) -389 min, query throws 30 min

packages/agenta-entities/tests/integration/trace-migration.integration.test.ts still builds designator-less bounds on purpose. Those assert the API accepts that form, which it still does, so they are left alone.

What to QA

  • Set your machine to a US timezone, open Observability and pick the 30 minutes range. The chart renders instead of showing the start/end error.
  • Set your machine to a positive offset (for example Europe/Istanbul), pick 30 minutes, and check the x-axis covers half an hour rather than several hours.
  • Regression: a custom start/end range and the "all time" preset both still return data.
  • Regression: the traces list on /observability uses the same sort control. Its 24 hour default still returns the last day.

toISOString().split(".")[0] dropped the trailing Z, and the value is later
re-read with dayjs(startTime) — which treats a designator-less stamp as LOCAL.
Measured against a 30-minute preset: UTC 30, Istanbul 210, New York -209,
Los Angeles -389. East of UTC the window is silently widened; west of it the
start lands in the future and fetchDashboardAnalytics throws "endTime must be
greater than or equal to startTime" instead of drawing a chart.

utcRangeStamp() joins the other date helpers and covers the preset, both
custom-range bounds and the two dashboard defaults; the all-time literal gets
the same designator.
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Aug 11, 2026
@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Blocked Blocked Aug 11, 2026 6:05am

Request Review

@dosubot dosubot Bot added bug report Something isn't working frontend labels Aug 11, 2026
@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 3e7f02dc-f59c-4c8a-88ef-2b2b81dadf3f

📥 Commits

Reviewing files that changed from the base of the PR and between 4af1551 and 98ee6eb.

📒 Files selected for processing (4)
  • web/oss/src/components/Filters/Sort.tsx
  • web/oss/src/lib/helpers/dateTimeHelper/index.ts
  • web/oss/src/state/newObservability/atoms/controls.ts
  • web/oss/src/state/observability/dashboard.ts

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved date-range filtering accuracy by consistently formatting timestamps in UTC.
    • Ensured preset, custom, default, and “all time” ranges use standardized second-level timestamps with the correct UTC suffix.

Walkthrough

The change adds utcRangeStamp and replaces manual UTC timestamp formatting in sort filters and observability state defaults. The all-time timestamp now includes an explicit Z suffix.

Changes

UTC timestamp standardization

Layer / File(s) Summary
UTC timestamp helper
web/oss/src/lib/helpers/dateTimeHelper/index.ts
Adds utcRangeStamp, which converts dates to UTC, truncates fractional seconds, and appends Z.
Date range formatting integrations
web/oss/src/components/Filters/Sort.tsx, web/oss/src/state/newObservability/atoms/controls.ts, web/oss/src/state/observability/dashboard.ts
Uses utcRangeStamp for filter ranges and observability defaults. The all-time value now has an explicit UTC suffix.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the frontend fix for analytics range bounds and preserved UTC designators.
Description check ✅ Passed The description directly explains the timezone defect, implementation, affected paths, and QA coverage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/observability-utc-range

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Status Destroyed (PR closed)

Updated at 2026-08-11T12:18:49.841Z

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Aug 11, 2026
@mmabrouk
mmabrouk merged commit 5643b13 into release/v0.112.0 Aug 11, 2026
63 of 64 checks passed
pull Bot pushed a commit to jasonkneen/agenta that referenced this pull request Aug 22, 2026
…s interactionRows

Two more of the deferred ports.

Agenta-AI#5927 -- SessionCardList showed the agent name but not the automation kind,
while SessionRow (which the merge updated) did. An automation row IS its
schedule/subscription, so without the kind it reads as a conversation someone
started. Now matches SessionRow.

Agenta-AI#5942 (package half) -- loadSessionMessages already fetched the interaction
lifecycle rows for replay (Agenta-AI#5919 brought that), but dropped them on the floor
instead of returning them. They are now threaded out as SessionTranscript.
interactionRows: records never carry a row's later lifecycle, so this is the
only place an adoption guard can tell a card still awaiting the user (`pending`)
from one that has ended.

Also verified Agenta-AI#5923 needs NO port: the lane's toRangeInstant is functionally
identical to the release's utcRangeStamp (second-precision UTC with the
load-bearing Z), already used at all five sites, with ALL_TIME_START covering
the epoch case. Filters/Sort.tsx does not exist on this lane.

oss tsc 0 errors, mobile tsc 0 errors.

This branch had an error being deployed

1 failed deployment
Preview — 98ee6eb5 Deployed Aug 11, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug report Something isn't working frontend lgtm This PR has been approved by a maintainer size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants