{"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":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/packets/encode_parameter.js","lineNumber":24,"sourceCode":"function 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    // eslint-disable-next-line no-invalid-this\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":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/sidorares/node-mysql2/blob/5ebe8903d6aea2d8ea1490e11b52491526e50f19/lib/packets/encode_parameter.js#L6-L42","documentation":"toParameter() is the low-level encoder for prepared-statement (binary protocol) bind values. It rejects `undefined` for the same reason the higher-level execute() check does: SQL has no representation for undefined, and the value must be `null` to mean SQL NULL. This is the final backstop on the encode path.","triggerScenarios":"An undefined value slipping into the binary execute parameter list after the higher-level execute() guard — e.g. calling the Execute command directly, a code path that builds the Execute packet without the connection.js guard, or a value that becomes undefined during parameter transformation.","commonSituations":"Using internal command classes directly; a prepared-statement code path that bypasses Connection.execute()'s pre-check; values mutated to undefined between validation and encoding.","solutions":["Sanitise the bind array so every undefined becomes null before execute: `values = values.map(v => v === undefined ? null : v)`.","Ensure you go through Connection.execute()/pool.execute() which validates first.","Trace where the undefined value originates and fix the source."],"exampleFix":"// before\nstmt.execute([id, maybeUndef]);\n\n// after\nstmt.execute([id, maybeUndef ?? null]);","handlingStrategy":"validation","validationCode":"function sanitizeBinds(values) {\n  return values.map((v) => (v === undefined ? null : v));\n}\nstmt.execute(sanitizeBinds(values));","typeGuard":"function bindsAreDefined(arr) {\n  return Array.isArray(arr) && arr.every((v) => v !== undefined);\n}","tryCatchPattern":null,"preventionTips":["Map undefined → null across every bind array before execute.","Route through Connection.execute() so the higher-level guard runs first.","Add a shared helper used by all prepared-statement call sites."],"tags":["bind-parameters","prepared-statements","binary-protocol"],"analyzedSha":"5ebe8903d6aea2d8ea1490e11b52491526e50f19","analyzedAt":"2026-08-03T18:58:53.602Z","schemaVersion":2}