{"record":{"id":"b6b04a9826b31313","repo":"sidorares/node-mysql2","slug":"bind-parameters-must-not-contain-undefined","errorCode":null,"errorMessage":"Bind parameters must not contain undefined","messagePattern":"Bind parameters must not contain undefined","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/packets/encode_parameter.js","lineNumber":23,"sourceCode":"\nfunction isJSON(value) {\n  return (\n    Array.isArray(value) ||\n    value.constructor === Object ||\n    (typeof value.toJSON === 'function' && !Buffer.isBuffer(value))\n  );\n}\n\nfunction toParameter(value, encoding, timezone, jsonAsString) {\n  let type = Types.VAR_STRING;\n  let length;\n  let writer = function (value) {\n    return Packet.prototype.writeLengthCodedString.call(this, value, encoding);\n  };\n  if (value !== null) {\n    switch (typeof value) {\n      case 'undefined':\n        throw new TypeError('Bind parameters must not contain undefined');\n\n      case 'number':\n        type = Types.DOUBLE;\n        length = 8;\n        writer = Packet.prototype.writeDouble;\n        break;\n\n      case 'boolean':\n        value = value | 0;\n        type = Types.TINY;\n        length = 1;\n        writer = Packet.prototype.writeInt8;\n        break;\n\n      case 'object':\n        if (Object.prototype.toString.call(value) === '[object Date]') {\n          type = Types.DATETIME;\n          length = 12;","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/sidorares/node-mysql2/blob/8b1f829d3706404ab372cf97bd77ebcf86578d97/lib/packets/encode_parameter.js#L5-L41","documentation":"toParameter in lib/packets/encode_parameter.js:14-24 encodes a single prepared-statement bind value; the typeof switch throws TypeError for 'undefined' because, unlike null (which maps to Types.NULL at line 67-70), undefined has no valid MySQL wire representation. This is the prepared-statement execution-time counterpart to the execute() pre-check in connection.js:797.","triggerScenarios":"A prepared-statement execute path that bypasses the connection.execute pre-check (e.g. a reused PreparedStatement with values containing undefined; an internal call to toParameter without prior validation); a value object that loses a key during serialization.","commonSituations":"Using the lower-level prepared-statement API directly; a custom execute wrapper that skips validation; sparse arrays as bind params ([1, , 3] where index 1 is a hole yielding undefined).","solutions":["Coalesce undefined to null before binding: values.map(v => v === undefined ? null : v).","Avoid sparse arrays as bind parameters.","Run the same Array.isArray + typeof validation that Connection.execute does, in any custom execute wrapper."],"exampleFix":"// before\nstmt.execute([maybeUndefined]);\n\n// after\nstmt.execute([maybeUndefined === undefined ? null : maybeUndefined]);","handlingStrategy":"validation","validationCode":"const safeParams = (vals) => vals.map(v => v === undefined ? null : v);\n// stmt.execute(safeParams(values));","typeGuard":"const hasNoUndefined = (vals) => vals.every(v => v !== undefined);","tryCatchPattern":null,"preventionTips":["Route all execute calls through a shared helper that runs the connection.execute-style validation.","Avoid sparse arrays as bind parameters."],"tags":["prepared-statements","bind-parameters","serialization","validation"],"backgroundTag":null,"analyzedSha":"8b1f829d3706404ab372cf97bd77ebcf86578d97","analyzedAt":"2026-08-11T02:54:28.964Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}