denoland/deno · error · RangeError
Failed to construct 'QuotaExceededError': quota must not be
Error message
Failed to construct 'QuotaExceededError': quota must not be negative
What it means
QuotaExceededError (ext/web/01_dom_exception.js:285, defined per WebIDL 4.3.1) is constructible in Deno with an options bag exposing quota/requested details. The 'quota' member is converted to an unrestricted double and must not be negative; a negative value throws this RangeError from the constructor, so the exception object is never produced.
Source
Thrown at ext/web/01_dom_exception.js:285
// Defined in WebIDL 4.3.1.
// https://webidl.spec.whatwg.org/#quotaexceedederror
class QuotaExceededError extends DOMException {
[_quota];
[_requested];
constructor(message = "", options = { __proto__: null }) {
super(message, "QuotaExceededError");
if (options !== null && typeof options === "object") {
if (ObjectHasOwn(options, "quota")) {
const quota = webidl.converters["unrestricted double"](
options.quota,
"Failed to construct 'QuotaExceededError'",
"'quota' member of QuotaExceededErrorOptions",
);
if (quota < 0) {
throw new RangeError(
"Failed to construct 'QuotaExceededError': quota must not be negative",
);
}
this[_quota] = quota;
} else {
this[_quota] = null;
}
if (ObjectHasOwn(options, "requested")) {
const requested = webidl.converters["unrestricted double"](
options.requested,
"Failed to construct 'QuotaExceededError'",
"'requested' member of QuotaExceededErrorOptions",
);
if (requested < 0) {
throw new RangeError(
"Failed to construct 'QuotaExceededError': requested must not be negative",
);
}View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Omit the quota member when unknown; it defaults to null
- Clamp before constructing: Math.max(0, quota)
- Validate the options bag with a guard so callers get your own error message instead of the constructor's
Example fix
// before
throw new QuotaExceededError('storage full', { quota: limit - used }); // can be -1
// after
throw new QuotaExceededError('storage full', {
quota: Math.max(0, limit - used),
}); Defensive patterns
Strategy: validation
Validate before calling
if (quota !== undefined && !(typeof quota === "number" && quota >= 0)) {
throw new RangeError("quota must be a non-negative number");
}
throw new QuotaExceededError(msg, { quota }); Type guard
const isNonNegativeNumber = (v: unknown): v is number => typeof v === "number" && Number.isFinite(v) && v >= 0;
Try / catch
try {
throw new QuotaExceededError(msg, options);
} catch (e) {
if (e instanceof RangeError && e.message.includes("quota must not be negative")) {
throw new QuotaExceededError(msg); // omit the details member
}
throw e;
} Prevention
- Clamp computed quota values with Math.max(0, x)
- Use null/omission instead of -1 sentinels for unknown quota
- Validate the whole options bag once before constructing the error
When it happens
Trigger: new QuotaExceededError('msg', { quota: -1 }); quota computed as limit - used underflowing below zero; passing a -1 sentinel meaning 'unknown'; forwarding unvalidated user input into the options bag.
Common situations: Wrapping storage/quota reporting APIs (e.g. navigator.storage.estimate style flows) that surface a QuotaExceededError with details; libraries using negative sentinels for missing values; unit tests probing constructor validation.
Related errors
- Failed to construct 'QuotaExceededError': requested must not
- InvalidStateError
- BenchContext::start() has already been invoked
- ${prefix}Linter plugin name must only contain lowercase lett
- ${prefix}Linter plugin name must start and end with a lowerc
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/55c6672664a50ba5.
Report an issue: GitHub.