Wei-Shaw/sub2api · error

failed to get usage trend

Error message

failed to get usage trend

What it means

Returned while assembling the v2 dashboard snapshot when includeTrend is true and h.getUsageTrendCached(...) fails. The cached helper wraps the usage-stats trend query; on failure the raw error is dropped and replaced with this generic message. Almost always a database/aggregation failure, not a filter syntax problem.

Source

Thrown at backend/internal/handler/admin/dashboard_snapshot_v2_handler.go:193

	if includeTrend {
		trend, _, err := h.getUsageTrendCached(
			ctx,
			startTime,
			endTime,
			granularity,
			filters.UserID,
			filters.APIKeyID,
			filters.AccountID,
			filters.GroupID,
			filters.Model,
			filters.RequestType,
			filters.Stream,
			filters.BillingType,
			filters.UpstreamModelMismatch,
		)
		if err != nil {
			return nil, errors.New("failed to get usage trend")
		}
		resp.Trend = trend
	}

	if includeModels {
		models, _, err := h.getModelStatsCached(
			ctx,
			startTime,
			endTime,
			filters.UserID,
			filters.APIKeyID,
			filters.AccountID,
			filters.GroupID,
			usagestats.ModelSourceRequested,
			filters.RequestType,
			filters.Stream,
			filters.BillingType,
			filters.UpstreamModelMismatch,

View on GitHub (pinned to 073e92d171)

Solutions

  1. Retry with a narrower date range or coarser granularity to reduce aggregation cost
  2. Check backend logs for the underlying trend query error
  3. Verify the usage-stats store is healthy (connectivity, timeouts, disk)
  4. Temporarily exclude the trend section from the snapshot while diagnosing
Defensive patterns

Strategy: retry

Validate before calling

// Cap request cost before calling
const days = (end - start) / 86400000;
if (includeTrend && days > 90 && granularity === 'hour') throw new Error('range too wide; coarsen granularity');

Try / catch

// TS
try { trend = await getSnapshotV2({ includeTrend: true, start, end, granularity }); }
catch (e) {
  if (e.message === 'failed to get usage trend') {
    trend = await withBackoff(() => getSnapshotV2({ includeTrend: true, start, end, granularity: 'day' }));
  } else throw e;
}

Prevention

When it happens

Trigger: GET dashboard snapshot v2 with the trend section included over a date range where the trend aggregation query fails (DB outage, timeout, malformed time-bucket parameters after the range parse).

Common situations: Very wide date ranges with fine granularity producing huge GROUP BY queries; DB maintenance windows; stale trend cache interacting with an evicted/expired entry.

Related errors


AI-assisted analysis of Wei-Shaw/sub2api@073e92d171 (2026-08-15). Data as JSON: /api/errors/fe82c775a651a538. Report an issue: GitHub.