{"record":{"id":"0953432609ef70c9","repo":"denoland/deno","slug":"failed-to-construct-quotaexceedederror-requeste","errorCode":null,"errorMessage":"Failed to construct 'QuotaExceededError': requested must not be negative","messagePattern":"Failed to construct 'QuotaExceededError': requested must not be negative","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"ext/web/01_dom_exception.js","lineNumber":300,"sourceCode":"          \"'quota' member of QuotaExceededErrorOptions\",\n        );\n        if (quota < 0) {\n          throw new RangeError(\n            \"Failed to construct 'QuotaExceededError': quota must not be negative\",\n          );\n        }\n        this[_quota] = quota;\n      } else {\n        this[_quota] = null;\n      }\n      if (ObjectHasOwn(options, \"requested\")) {\n        const requested = webidl.converters[\"unrestricted double\"](\n          options.requested,\n          \"Failed to construct 'QuotaExceededError'\",\n          \"'requested' member of QuotaExceededErrorOptions\",\n        );\n        if (requested < 0) {\n          throw new RangeError(\n            \"Failed to construct 'QuotaExceededError': requested must not be negative\",\n          );\n        }\n        this[_requested] = requested;\n      } else {\n        this[_requested] = null;\n      }\n    } else {\n      this[_quota] = null;\n      this[_requested] = null;\n    }\n  }\n\n  get quota() {\n    webidl.assertBranded(this, QuotaExceededErrorPrototype);\n    return this[_quota];\n  }\n","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/web/01_dom_exception.js#L282-L318","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Omit requested when unknown; it defaults to null","Clamp: Math.max(0, requested)","Validate both quota and requested together before constructing the error"],"exampleFix":"// before\nthrow new QuotaExceededError('quota hit', { requested: req }); // req = -1 on error\n\n// after\nthrow new QuotaExceededError('quota hit', {\n  requested: req >= 0 ? req : 0,\n});","handlingStrategy":"validation","validationCode":"if (requested !== undefined && !(typeof requested === \"number\" && requested >= 0)) {\n  throw new RangeError(\"requested must be a non-negative number\");\n}\nthrow new QuotaExceededError(msg, { requested });","typeGuard":"const isNonNegativeNumber = (v: unknown): v is number =>\n  typeof v === \"number\" && Number.isFinite(v) && v >= 0;","tryCatchPattern":"try {\n  throw new QuotaExceededError(msg, options);\n} catch (e) {\n  if (e instanceof RangeError && e.message.includes(\"requested must not be negative\")) {\n    throw new QuotaExceededError(msg); // omit the details member\n  }\n  throw e;\n}","preventionTips":["Clamp requested sizes with Math.max(0, x) before constructing the error","Omit the requested member when the failed write size is unknown","Validate quota and requested with one shared guard in error-reporting code"],"tags":["dom-exception","quota","storage","validation"],"backgroundTag":"negative-value-rejected","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}