vercel-labs/agent-skills · warning

DAILY_QUOTA_EXCEEDED

DAILY_QUOTA_EXCEEDED

Error message

DAILY_QUOTA_EXCEEDED

What it means

Constructed by dailyQuotaResult() from a cached dailyQuotaBlock and returned (not thrown) when the Vercel Observability daily query quota was exhausted earlier in the session. setDailyQuotaBlocked() records the block with untilMs = next UTC midnight (utcMidnightAfter); subsequent metric calls short-circuit via getDailyQuotaBlock() and return this synthetic {ok:false, code:'DAILY_QUOTA_EXCEEDED', cachedUntil} result, preserving the original failing code/ message. This avoids hammering the API after the limit is hit.

Solutions

  1. Wait until the cachedUntil timestamp (next UTC midnight) for the quota to reset, then rerun.
  2. Reduce query volume: narrow the time window, fewer routes/groupBy dimensions, or run collect-signals once per day.
  3. Upgrade the Vercel plan / Observability tier to raise the daily query ceiling.
  4. If a stale block lingers, it clears automatically at UTC midnight via getDailyQuotaBlock's untilMs check.

Example fix

// before — block active, every call returns the quota error
const r = await runMetrics(...); // r.code === 'DAILY_QUOTA_EXCEEDED', cachedUntil set

// after — check the block first and degrade gracefully
import { getDailyQuotaBlock } from './lib/throttle.mjs';
const block = getDailyQuotaBlock();
if (block) {
  console.warn(`Observability quota exhausted until ${new Date(block.untilMs).toISOString()}; using cached signals.`);
  return cachedSignals;
}
const r = await runMetrics(...);
Defensive patterns

Strategy: fallback

Validate before calling

import { getDailyQuotaBlock } from './lib/throttle.mjs';
// before issuing any metrics query
const block = getDailyQuotaBlock();
if (block) {
  console.warn(`Daily Observability quota exhausted until ${new Date(block.untilMs).toISOString()}`);
  return cachedOrPartialSignals; // degrade instead of hitting the limit again
}

Type guard

function isDailyQuotaResult(r) {
  return !!r && r.ok === false && r.code === 'DAILY_QUOTA_EXCEEDED';
}

Try / catch

const r = await runMetrics(...);
if (isDailyQuotaResult(r)) {
  // not a throw — a returned result: fall back to cached signals and surface cachedUntil
  console.warn(`Quota hit; using cached signals until ${r.cachedUntil}`);
  return cachedSignals;
}
return r;

Prevention

When it happens

Trigger: collect-signals (or any metrics query) triggered the Observability daily limit; isDailyQuotaExceeded() detected it; setDailyQuotaBlocked() cached the block; every later metrics/usage call returns DAILY_QUOTA_EXCEEDED until the next UTC midnight resets it.

Common situations: A large project with many routes exhausting the daily Observability query budget; repeated collect-signals runs in the same day compounding usage; a team on a plan with a low Observability query ceiling.

Related errors


AI-assisted analysis of vercel-labs/agent-skills@b8caa260a4 (2026-08-13). Data as JSON: /api/errors/71ca87bb0c7a3979. Report an issue: GitHub.

Appendix: source

Thrown at skills/vercel-optimize/lib/throttle.mjs:264

export function getDailyQuotaBlock(nowMs = Date.now()) {
  if (!dailyQuotaBlock) return null;
  if (dailyQuotaBlock.untilMs <= nowMs) {
    dailyQuotaBlock = null;
    return null;
  }
  return dailyQuotaBlock;
}

export function utcMidnightAfter(nowMs) {
  const d = new Date(nowMs);
  return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate() + 1);
}

function dailyQuotaResult(block, sourceResult = null) {
  return {
    ...(sourceResult && typeof sourceResult === 'object' ? sourceResult : {}),
    ok: false,
    code: 'DAILY_QUOTA_EXCEEDED',
    message: block.message,
    cachedUntil: new Date(block.untilMs).toISOString(),
    originalCode: sourceResult?.originalCode ?? sourceResult?.code ?? block.originalCode ?? undefined,
  };
}

function defaultSleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

View on GitHub (pinned to b8caa260a4)