mastra-ai/mastra · error · Error
TokenCostControl requires warnAtPercent to be a number betwe
Error message
TokenCostControl requires warnAtPercent to be a number between 0 and 100 (exclusive)
What it means
TokenCostControl supports an early-warning threshold at a percentage of the budget. `warnAtPercent` is optional, but when provided it must be a finite number strictly between 0 and 100 (both endpoints excluded) — 0 would warn always and 100 would only warn when the cap is already hit, neither of which is meaningful. The constructor throws otherwise.
Source
Thrown at packages/core/src/processors/processors/token-cost-control.ts:266
private scope: CostScope;
private window: CostWindow;
private strategy: 'block' | 'warn';
private messageTemplate: string;
private warnAtPercent?: number;
private includeBreakdown: boolean;
private readonly instanceKey = tokenCostControlInstanceCounter++;
public onViolation?: (violation: ProcessorViolation) => void | Promise<void>;
private observabilityStorage?: ObservabilityStorage;
private logger?: IMastraLogger;
constructor(options: TokenCostControlOptions) {
if (typeof options.maxCost === 'number' && (!Number.isFinite(options.maxCost) || options.maxCost <= 0)) {
throw new Error('TokenCostControl requires maxCost to be a finite positive number');
}
if (options.warnAtPercent !== undefined) {
if (!Number.isFinite(options.warnAtPercent) || options.warnAtPercent <= 0 || options.warnAtPercent >= 100) {
throw new Error('TokenCostControl requires warnAtPercent to be a number between 0 and 100 (exclusive)');
}
this.warnAtPercent = options.warnAtPercent;
}
this.maxCost = options.maxCost;
this.scope = options.scope ?? 'resource';
this.window = options.window ?? '7d';
this.strategy = options.strategy ?? 'block';
this.messageTemplate = options.message ?? 'Cost control: estimated cost limit exceeded ({usage}/{limit})';
this.includeBreakdown = options.includeBreakdown ?? false;
}
__registerMastra(mastra: Mastra<any, any, any, any, any, any, any, any, any, any>): void {
const storage = mastra.getStorage();
const obsStorage = storage?.stores?.observability;
if (!obsStorage || typeof obsStorage.getMetricAggregate !== 'function') {
throw new Error(
`TokenCostControl requires observability storage with getMetricAggregate support. ` +View on GitHub (pinned to 75dd419e61)
Solutions
- Provide a percentage strictly between 0 and 100, e.g. `warnAtPercent: 80`.
- Convert fractions to percent: `warnAtPercent: fraction * 100`.
- Clamp/sanitize: `Math.min(99.9, Math.max(0.1, value))`.
- Omit the option entirely if no early warning is needed.
Example fix
// before
new TokenCostControl({ maxCost: 10, warnAtPercent: 0.8 });
// after
new TokenCostControl({ maxCost: 10, warnAtPercent: 80 }); Defensive patterns
Strategy: validation
Validate before calling
const v = options.warnAtPercent;
if (v !== undefined && (!Number.isFinite(v) || v <= 0 || v >= 100)) {
throw new TypeError(`warnAtPercent must be between 0 and 100 (exclusive), got ${v}`);
} Type guard
function isValidWarnPercent(v: unknown): v is number {
return typeof v === 'number' && Number.isFinite(v) && v > 0 && v < 100;
} Try / catch
try {
controller = new TokenCostControl(opts);
} catch (e) {
if (e.message.includes('warnAtPercent')) {
controller = new TokenCostControl({ ...opts, warnAtPercent: undefined });
} else throw e;
} Prevention
- Remember the option is a percent (0-100), not a fraction (0-1); multiply fractions by 100.
- Clamp UI slider/config values into (0, 100) exclusive before passing.
- Omit the option when no early warning is needed instead of using 0/100 as 'always'/'never'.
When it happens
Trigger: `new TokenCostControl({ maxCost: 10, warnAtPercent: 0 })`, `warnAtPercent: 100`, `warnAtPercent: -20`, `warnAtPercent: NaN/Infinity`, or a float like `0.05` intended as a fraction (0–1 scale) instead of a percentage (0–100 scale).
Common situations: Confusing fraction with percent (0.8 meaning 80%), loading the value from a slider/config that allows edge values, division producing NaN, or forgetting it is exclusive of the bounds.
Understand the failure class
Background: "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE) — this error's family across 28 libraries.
Related errors
- TokenCostControl requires maxCost to be a finite positive nu
- Platform integration: missing required config field(s): ${mi
- RegexFilterProcessor requires at least one rule or preset
- RegexFilterProcessor streamCarryoverSize must be a positive
- Better Auth instance is required. Please provide the auth op
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/ef5d2d8bcdf92688.
Report an issue: GitHub.