Skip to content

vitals crashes/anr fail with HTTP 400 because the query uses FULL_RANGE #9

Description

@alsd4git

Problem

vitals crashes --days 7 and vitals anr --days 7 fail with a Google Play Developer
Reporting API HTTP 400 on v0.5.17. The tagged source builds a FULL_RANGE timeline,
but the crash-rate and ANR-rate query methods support DAILY and HOURLY.

The same profiles can read tracks and make valid direct Reporting API queries.
This isolates the failure to Vitals query construction rather than authentication
or rate limiting.

Environment

  • Windows, PowerShell.
  • playconsole-cli v0.5.17.
  • Commit aa0b97a.
  • Build 2026-09-10T23:45:08Z.
  • Reproduced on 8 October 2026.
  • gpc below is the installed CLI executable.
  • Profile and package identifiers are anonymized.

The GitHub latest release still reports v0.5.17. I also checked master, which
retains the same relevant FULL_RANGE implementation as of this report.

Reproduction

Use an existing profile with Reporting API access and an accessible application:

gpc --profile <profile> --package <package> tracks list
gpc --profile <profile> --package <package> vitals crashes --days 7
gpc --profile <profile> --package <package> vitals anr --days 7

The track read succeeds. Both Vitals commands fail with HTTP 400. Google's error
says that the requested metrics, dimensions and aggregation period do not match
an allowed combination. Its listed alternatives use HOURLY or DAILY.

There was also an earlier failure of vitals overview with the same type of
combination error. I did not repeat the overview call during this diagnosis,
because it queries several metric sets and the shared code already explains why
the crash/ANR query fails.

The command help exposes --days, but no aggregation-period override. Changing
the requested date range cannot change the hardcoded FULL_RANGE value.

Source evidence

In the v0.5.17 Vitals implementation:

Google documents these supported aggregations for both query methods:

  • DAILY, with America/Los_Angeles as the supported timezone.
  • HOURLY, with UTC as the supported timezone. The 28-day rolling metrics are not
    supported in hourly queries.

References: crash-rate query
and ANR-rate query.

Successful read-only comparison

Direct calls to the same Reporting API, authenticated with the same affected
profiles, succeeded with HTTP 200 when using supported combinations:

Aggregation Timezone Dimensions Metrics
DAILY America/Los_Angeles versionCode userPerceivedCrashRate, distinctUsers
DAILY America/Los_Angeles versionCode userPerceivedAnrRate, distinctUsers
HOURLY UTC versionCode userPerceivedCrashRate, distinctUsers
HOURLY UTC versionCode userPerceivedAnrRate, distinctUsers

The queries used a version-code equality filter and the metric set's advertised
freshness boundary for the end time. Some returned rows and some returned an empty
result successfully. This also demonstrates that an empty dataset is distinct
from the invalid-combination error.

I then ran an isolated comparison with the exact metric lists used by the CLI,
without dimensions or filters. For each metric set, credentials, metrics, timezone
and the seven-day date window were identical. Only aggregationPeriod changed:

Metric set Aggregation HTTP response Result
crashRateMetricSet FULL_RANGE 400 Invalid metrics/dimensions/aggregation combination
crashRateMetricSet DAILY 200 Seven daily rows, no continuation token
anrRateMetricSet FULL_RANGE 400 Invalid metrics/dimensions/aggregation combination
anrRateMetricSet DAILY 200 Seven daily rows, no continuation token

The matched window was 29 September 2026 inclusive to 6 October exclusive in
America/Los_Angeles, using the reported DAILY freshness boundary. The crash
metrics were crashRate, crashRate7dUserWeighted, crashRate28dUserWeighted and
distinctUsers. The ANR metrics were anrRate, anrRate7dUserWeighted,
anrRate28dUserWeighted, userPerceivedAnrRate and distinctUsers.

This reproduces the failure and demonstrates that changing the aggregation fixes
the request for both exact CLI metric selections. It does not validate the CLI's
multi-row summary logic. No credentials, authorization headers or app identifiers
are included here.

Earlier observations

An earlier vitals overview --days 7 invocation on 6 October returned the same
400 from its crash-rate query. Historical stability checks in our records used
the Play Console UI instead. I have not established a previously working CLI
Vitals version or a date when Google's behavior changed, so this report does not
claim a new regression caused by v0.5.17.

Proposed fix and related result handling

I propose using DAILY for the crash/ANR date-range queries, retaining the
America/Los_Angeles timezone and selecting an end boundary covered by the metric
set's freshness. Any hourly option must use UTC and hourly-compatible metrics.
Because timelineSpec() is shared with other metric sets, its callers should be
checked before changing its aggregation globally.

Changing the aggregation string alone would leave a result-handling problem.
firstRowMetrics, line 713
reads only rows[0]. A daily query returns a time series, so that row cannot be
presented as a summary of an arbitrary multi-day window. The fix should handle
every returned row and pagination, and define whether the CLI returns dated rows
or an explicitly labelled summary.

For a summary, daily rates need the documented user weighting. Rolling 7-day and
28-day metrics must retain their own time semantics rather than being averaged
again or labelled as an arbitrary --days window. Google's rounded
distinctUsers values must not be summed and labelled as unique users across
the whole period, because the same person can appear on multiple days or hours.

There is also a related no-data issue.
optionalMetrics, line 699
converts missing data to an empty map with a warning.
runOverview, line 243
then reads absent keys as numeric zero. Machine-readable output should distinguish
unavailable data from a measured zero, even when the warning appears on stderr.

Suggested regression coverage

  • Generated crash/ANR requests use supported aggregation, timezone and metrics.
  • Query windows respect freshness and exclusive end boundaries.
  • Multiple returned rows, unordered rows and pagination are handled intentionally.
  • Rolling metrics and any period summary have explicit, correct time semantics.
  • Rounded daily/hourly user counts are not reported as unique multi-day users.
  • Empty responses remain unavailable in overview output; actual zero rates remain
    measured zeros.
  • Existing shared-timeline callers keep valid request combinations.

I would be happy to prepare a PR with the request fix and regression tests if this
approach fits the project. Before implementing it, I would welcome your preference
on preserving the current summary output versus exposing dated metric rows.

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

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions