denoland/deno · error · RangeError

Failed to construct 'QuotaExceededError': requested must not

Error message

Failed to construct 'QuotaExceededError': requested must not be negative

What it means

The second validated member of QuotaExceededErrorOptions (ext/web/01_dom_exception.js:300): 'requested' is converted to an unrestricted double and rejected when negative. The RangeError is thrown from the constructor after quota was already processed, so a negative 'requested' alone is enough to abort construction of the DOMException subclass.

Source

Thrown at ext/web/01_dom_exception.js:300

          "'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",
          );
        }
        this[_requested] = requested;
      } else {
        this[_requested] = null;
      }
    } else {
      this[_quota] = null;
      this[_requested] = null;
    }
  }

  get quota() {
    webidl.assertBranded(this, QuotaExceededErrorPrototype);
    return this[_quota];
  }

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Omit requested when unknown; it defaults to null
  2. Clamp: Math.max(0, requested)
  3. Validate both quota and requested together before constructing the error

Example fix

// before
throw new QuotaExceededError('quota hit', { requested: req }); // req = -1 on error

// after
throw new QuotaExceededError('quota hit', {
  requested: req >= 0 ? req : 0,
});
Defensive patterns

Strategy: validation

Validate before calling

if (requested !== undefined && !(typeof requested === "number" && requested >= 0)) {
  throw new RangeError("requested must be a non-negative number");
}
throw new QuotaExceededError(msg, { requested });

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("requested must not be negative")) {
    throw new QuotaExceededError(msg); // omit the details member
  }
  throw e;
}

Prevention

When it happens

Trigger: new QuotaExceededError('msg', { requested: -1 }); requested derived from a size measurement that failed and defaulted to a negative sentinel; passing through caller-supplied sizes unvalidated.

Common situations: Reporting how many bytes a failed write requested when the measurement errors out; -1 sentinels from C-style APIs leaking into the options bag; tests constructing the error with edge-case numbers.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/0953432609ef70c9. Report an issue: GitHub.