In Drupal 8 I am trying to insert some data in my custom table. While executing query I am getting error:

InvalidArgumentException: Placeholders must have a trailing [] if they are to be expanded with an array of values. in Drupal\Core\Database\Connection->expandArguments()

Please find my code below:

$qt = new \stdClass();
$qt->name = 'test name';
$qt->machine_name = 'test machine name';
$qt->settings = array('setting1'=>value1, 'setting2'=>value2);

$query = \Drupal::database()->insert('my_custom_table');

If I am giving values like below it is working. Please help me whats wrong with above code.

  • FYI, the fields method can contain associative arrays in a ['key' => 'value'] format – Eyal Jun 23 '16 at 23:11

That issue got resolved. It was regarding passing array in to the db. Added serialise function resloved the issue.


This is all explained in the Drupal documentation. If you are forming a query that can take an array of arguments, then the (arbitrary) placeholder string needs to indicate this. So a placeholder of :column will only work for a single value, but if you want to use an array of values you need to use the syntax :column[].

See https://www.drupal.org/docs/drupal-apis/database-api/static-queries#placeholder-arrays

Specifically, from the documentation, you can use (for example):

$result = $database->query("SELECT * FROM {mytable} WHERE id IN (:ids[])", [':ids[]' => [13, 42, 144]]);

OR you can use (for example):

$result = $database->query("SELECT * FROM {mytable} WHERE id IN (:ids_1, :ids_2, :ids_3)", [
  ':ids_1' => 13, 
  ':ids_2' => 42, 
  ':ids_3' => 144,

But you CANNOT use (for example):

$result = $database->query("SELECT * FROM {mytable} WHERE id IN (:ids)", [':ids' => [13, 42, 144]]);

because in this case you're passing in an array ( [13, 42, 144] ) but the placeholder ( :ids ) does not use the proper syntax for array placeholders.


that also happen to me when adding a string to an expected int so casting was necessary


My issue had to do with logging something incorrectly:

 $this->myLogger->log('My message @somePlaceholder', ['@somePlaceholder' => 'hi']);

But from the documentation Logger::log(), the first parameter was supposed to be $level.

I just switched to Logger::info()

 $this->myLogger->info('My message @somePlaceholder', ['@somePlaceholder' => 'hi']);
  • Your code isn't even syntactically valid. And log() vs. info() has nothing to do with this error. – anonymous Dec 23 '20 at 1:21
  • Hi @anonymous, thanks for pointing out my typo... I tried running the equivalence of \Drupal::logger('my_logger')->log('My message @somePlaceholder', ['@somePlaceholder' => 'hi']) and got this error. Could you test? – Chris Happy Dec 23 '20 at 1:23
  • The logger service does eventually put the logged information into the database, so somewhere under the hood Drupal is performing a database query to store the information using the parameters you passed. In your case, because you called log() with the wrong arguments, an array was passed to the code that performs the database query, but it was expecting a string not an array. You evidently triggered this error for that reason. You should have instead called $this->myLogger->log(LogLevel::INFO, 'My message @somePlaceholder', ['@somePlaceholder' => 'hi']); – anonymous Dec 23 '20 at 1:46
  • @anonymous Exactly. When I realized that ::log() did not provide a default level after an hour of debugging (>.>), I decided to post here in case anyone encountered the same error :) – Chris Happy Dec 23 '20 at 2:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.