{"id":"3bf99159891e2645","repo":"sidorares/node-mysql2","slug":"bind-parameters-must-be-array-if-namedplaceholders","errorCode":null,"errorMessage":"Bind parameters must be array if namedPlaceholders parameter is not enabled","messagePattern":"Bind parameters must be array if namedPlaceholders parameter is not enabled","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/base/connection.js","lineNumber":777,"sourceCode":"      } else {\n        options.values = options.values || values;\n      }\n    } else if (typeof values === 'function') {\n      // execute(sql, cb)\n      cb = values;\n      options.sql = sql;\n      options.values = undefined;\n    } else {\n      // execute(sql, values, cb)\n      options.sql = sql;\n      options.values = values;\n    }\n    this._resolveNamedPlaceholders(options);\n    // check for values containing undefined\n    if (options.values) {\n      //If namedPlaceholder is not enabled and object is passed as bind parameters\n      if (!Array.isArray(options.values)) {\n        throw new TypeError(\n          'Bind parameters must be array if namedPlaceholders parameter is not enabled'\n        );\n      }\n      options.values.forEach((val) => {\n        //If namedPlaceholder is not enabled and object is passed as bind parameters\n        if (!Array.isArray(options.values)) {\n          throw new TypeError(\n            'Bind parameters must be array if namedPlaceholders parameter is not enabled'\n          );\n        }\n        if (val === undefined) {\n          throw new TypeError(\n            'Bind parameters must not contain undefined. To pass SQL NULL specify JS null'\n          );\n        }\n        if (typeof val === 'function') {\n          throw new TypeError(\n            'Bind parameters must not contain function(s). To pass the body of a function as a string call .toString() first'","sourceCodeStart":759,"sourceCodeEnd":795,"githubUrl":"https://github.com/sidorares/node-mysql2/blob/5ebe8903d6aea2d8ea1490e11b52491526e50f19/lib/base/connection.js#L759-L795","documentation":"In Connection.execute(), after named-placeholder resolution, the bind values are required to be an array. If `options.values` is not an array (e.g. a plain object) and `namedPlaceholders` is not enabled in the connection config, mysql2 throws because it cannot map an object's keys to `?` placeholders. Named-placeholder support must be explicitly opted into via the `namedPlaceholders: true` config.","triggerScenarios":"Calling `connection.execute('SELECT * FROM t WHERE a = ? AND b = ?', { a: 1, b: 2 })` (passing an object) without `namedPlaceholders: true`. Or passing an object to `.query()`/`.execute()` values when the config flag is off. Also triggered by accidentally passing a single non-array argument where an array of bind values is expected.","commonSituations":"Developer assumes object-style parameters work by default (they do in some ORMs); copy-pasting query syntax from a library that uses named params; forgetting to set `namedPlaceholders: true` when migrating from another driver.","solutions":["Pass bind parameters as an array: `connection.execute(sql, [1, 2])`.","Or enable named placeholders in config: `mysql.createConnection({ ..., namedPlaceholders: true })` and use `:name` placeholders in SQL."],"exampleFix":"// before\nconnection.execute('SELECT * FROM t WHERE a = ? AND b = ?', { a: 1, b: 2 });\n\n// after — option A: array\nconnection.execute('SELECT * FROM t WHERE a = ? AND b = ?', [1, 2]);\n\n// after — option B: enable named placeholders\nmysql.createConnection({ host, namedPlaceholders: true });\nconnection.execute('SELECT * FROM t WHERE a = :a AND b = :b', { a: 1, b: 2 });","handlingStrategy":"validation","validationCode":"function normalizeParams(values, namedPlaceholders) {\n  if (values != null && !Array.isArray(values)) {\n    if (!namedPlaceholders) {\n      throw new TypeError('Pass an array, or enable namedPlaceholders: true');\n    }\n  }\n  return values;\n}\n// usage:\nconst v = normalizeParams(values, conn.config.namedPlaceholders);\nconn.execute(sql, v);","typeGuard":"function isBindableArray(values) {\n  return Array.isArray(values);\n}","tryCatchPattern":null,"preventionTips":["Standardise on arrays for `?` placeholders across the codebase.","Enable namedPlaceholders explicitly if you want object params.","Lint for object literals passed as the second arg to execute/query."],"tags":["query","prepared-statements","bind-parameters"],"analyzedSha":"5ebe8903d6aea2d8ea1490e11b52491526e50f19","analyzedAt":"2026-08-03T18:58:53.602Z","schemaVersion":2}