{"record":{"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":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/base/connection.js","lineNumber":785,"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":767,"sourceCodeEnd":803,"githubUrl":"https://github.com/sidorares/node-mysql2/blob/8b1f829d3706404ab372cf97bd77ebcf86578d97/lib/base/connection.js#L767-L803","documentation":"In Connection.execute (lib/base/connection.js:782-788), after resolving named placeholders, if options.values is truthy but not an Array, the driver throws because positional ? placeholders require an array. Passing an object of named values is only valid when config.namedPlaceholders is enabled; otherwise the driver cannot map keys to ? slots.","triggerScenarios":"Calling connection.execute('SELECT * FROM t WHERE id = ?', { id: 1 }) without namedPlaceholders; passing a Map or object where an array is expected; mixing the named-parameter style from another driver (pg, mysql2 promise) into a positional execute call.","commonSituations":"Copy-paste from a pg/node-postgres codebase that uses object params; refactoring a query helper that previously built arrays; confusion between ? and :name placeholder styles.","solutions":["Pass an array: connection.execute(sql, [1]).","Or enable named placeholders: createConnection({ ..., namedPlaceholders: true }) and use :name in SQL with a params object.","If building params dynamically, wrap with Array.from(...) or validate Array.isArray before the call."],"exampleFix":"// before\nconnection.execute('SELECT * FROM t WHERE id = ?', { id: 1 });\n\n// after (positional)\nconnection.execute('SELECT * FROM t WHERE id = ?', [1]);\n// after (named)\nconnection.execute('SELECT * FROM t WHERE id = :id', { id: 1 }); // needs namedPlaceholders: true","handlingStrategy":"validation","validationCode":"function assertBindArray(values) {\n  if (values && !Array.isArray(values)) {\n    throw new TypeError('Pass an array for positional placeholders, or enable namedPlaceholders for an object.');\n  }\n}\n// assertBindArray(values) before conn.execute(sql, values);","typeGuard":"const isBindArray = (v) => Array.isArray(v);","tryCatchPattern":null,"preventionTips":["Standardize on positional arrays across the codebase unless named placeholders are deliberately enabled.","Lint against passing object literals to .execute() in modules without namedPlaceholders."],"tags":["prepared-statements","bind-parameters","api-usage","validation"],"backgroundTag":null,"analyzedSha":"8b1f829d3706404ab372cf97bd77ebcf86578d97","analyzedAt":"2026-08-11T02:54:28.964Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}