{"record":{"id":"933cc676394b6c5b","repo":"denoland/deno","slug":"err-invalid-arg-value-933cc6","errorCode":"ERR_INVALID_ARG_VALUE","errorMessage":"The property 'options.${key}' is invalid. Received ${value}","messagePattern":"The property 'options\\.(.+?)' is invalid\\. Received (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/cipher.ts","lineNumber":489,"sourceCode":"  }\n\n  set lastChunkIsNonZero(value: boolean) {\n    this.#lastChunkIsNonZero = value;\n  }\n}\n\nfunction getBlockSize(cipher: string): number {\n  if (StringPrototypeStartsWith(cipher, \"des\")) {\n    return 8;\n  }\n  return 16;\n}\n\nfunction getUIntOption(options, key) {\n  let value;\n  if (options && (value = options[key]) != null) {\n    if (value >>> 0 !== value) {\n      throw new ERR_INVALID_ARG_VALUE(`options.${key}`, value);\n    }\n    return value;\n  }\n  return -1;\n}\n\nfunction Decipheriv(\n  cipher: string,\n  key: any,\n  iv: any,\n  options?: any,\n) {\n  if (!ObjectPrototypeIsPrototypeOf(Decipheriv.prototype, this)) {\n    return new Decipheriv(cipher, key, iv, options);\n  }\n\n  const authTagLength = getUIntOption(options, \"authTagLength\");\n","sourceCodeStart":471,"sourceCodeEnd":507,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/cipher.ts#L471-L507","documentation":"getUIntOption() reads numeric constructor options such as authTagLength and requires value >>> 0 === value, i.e. a valid uint32. Negative numbers, fractional numbers, NaN, values above 4294967295, and non-number types all fail the check and throw ERR_INVALID_ARG_VALUE on 'options.<key>' (e.g. options.authTagLength). Used by both Cipheriv and Decipheriv option handling.","triggerScenarios":"createDecipheriv('aes-128-gcm', key, iv, { authTagLength: -1 }); { authTagLength: 4.5 }; { authTagLength: '16' } (string from config/JSON); authTagLength parsed from a protocol header without numeric conversion.","commonSituations":"Options loaded from JSON/YAML where numbers arrive as strings; tag lengths computed from arithmetic that can go negative or fractional; environment variables passed straight into options.","solutions":["Pass a non-negative integer between 0 and 4294967295, e.g. authTagLength: 16.","Sanitize before the call: Number.isInteger(x) && x >= 0 && x <= 0xFFFFFFFF.","Type the options object (authTagLength?: number) so strings are caught at compile time."],"exampleFix":"// before\nconst d = crypto.createDecipheriv('aes-128-gcm', key, iv, { authTagLength: cfg.tagLen }); // cfg.tagLen = \"16\"\n\n// after\nconst tagLen = Number(cfg.tagLen);\nif (!Number.isInteger(tagLen) || tagLen < 0) throw new Error('bad tagLen');\nconst d = crypto.createDecipheriv('aes-128-gcm', key, iv, { authTagLength: tagLen });","handlingStrategy":"validation","validationCode":"function validateUIntOption(value: unknown, name: string): number {\n  const n = typeof value === 'string' ? Number(value) : value;\n  if (typeof n !== 'number' || !Number.isInteger(n) || n < 0 || n > 0xFFFFFFFF)\n    throw new TypeError(`options.${name} must be a uint32, got ${String(value)}`);\n  return n;\n}\nconst opts = { authTagLength: validateUIntOption(cfg.authTagLength, 'authTagLength') };","typeGuard":"function isUInt32(v: unknown): v is number {\n  return typeof v === 'number' && Number.isInteger(v) && v >= 0 && v <= 0xFFFFFFFF;\n}","tryCatchPattern":null,"preventionTips":["Convert config strings to numbers before putting them in crypto options.","Declare option types as `number` in TS interfaces to catch string literals.","Never compute authTagLength with arithmetic that can produce negatives or fractions."],"tags":["crypto","cipher","options","argument-validation","node-compat"],"backgroundTag":"invalid-option-value","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T10:36:37.832Z"}