Thursday, April 17, 2008

Drupal Invalid argument supplied for foreach error

I've been getting this really weird error and could not track it for sometime but have finally managed to figure out a way to get rid of it, so perhaps others might find this useful too.

Summary: it was caused by a call to node_load() method passing nothing as an argument. So check if you have some code that assumes that an ID of a node is present and calls that function!

Long story:
First of all, my page would show in the central area a warning message like this:

* warning: Invalid argument supplied for foreach() in C:\Program Files\Apache Group\Apache2\htdocs\mcsonline\modules\node\node.module on line 521.
* warning: implode() [function.implode]: Bad arguments. in C:\Program Files\Apache Group\Apache2\htdocs\mcsonline\modules\node\node.module on line 525.
* user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 query: SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM node n INNER JOIN users u ON u.uid = n.uid INNER JOIN node_revisions r ON r.vid = n.vid WHERE in C:\Program Files\Apache Group\Apache2\htdocs\mcsonline\includes\database.mysql.inc on line 172.
Searching around led me to some other people complaining about the error but the major difference is that there was usually a hint in that the error would refer to a specific module. In my case, however, it was talking about the core node module! Not much help there.

First thing to do: try and figure out where is the error coming from. :) OK, so I suppose that's an obvious one. But honestly I was stuck a bit wondering where to start. So one easy way is to start turning off blocks until you can see that the error disappears. So this led me to a specific block which was actually a view (I'm using a module to display views as blocks which I know can't remember the name).

Next, after realizing that there was nothing interesting about the view since it just did a List View of a couple of CCK fields and a title for a user-defined content type I was off to search elsewhere. Since my memory does not serve me that well it took me a while to remember to check template.php since I could be overriding the list view (using the phptemplate_views_view_list_VIEW-NAME($view, $nodes, $type)). So there it was - a small snippet getting the view in question to render through a template.

Now the really really weird thing was that the view was showing the content - I saw a single item that I was supposed to see but I get the warning message as well (hm, now I realize its a "warning"). So it meant that the method did something wrong partially but managed to proceed.

Some context here: a day before I was actually removing some CCK fields from content types and I had this author field that I've removed for the (now problematic) event content type.

In the function that I had there was a line like:
$auth = node_load($targetnode->field_autor[0]['nid']);
I did this regardless of whether the author field was there or not! (hm, this is supposed to be a small helper method used when rendering list views so ...).

Doing a check if the field is there before calling node_load did the trick! Yay.

6 comments:

OLED said...

Hello. This post is likeable, and your blog is very interesting, congratulations :-). I will add in my blogroll =). If possible gives a last there on my blog, it is about the OLED, I hope you enjoy. The address is http://oled-brasil.blogspot.com. A hug.

JINQIU said...

That is not because the element in foreach is not an array?

I use

if(is_array($_element))
{
foreach($_element as $value)
}

and all issues are disappeared.

Aleks said...

drupal warning: Invalid argument supplied for foreach() in content.views.inc

OR

drupal warning: Invalid argument supplied for foreach() in /cck/cck/includes/views/content.views.inc on line 139.

SOLUCIÓN /SOLUTION

Ir al Informe de Estado de Drupal actualizar todo y revisar los errores.

Go to status reports and udpate the errors list.

mk said...

This blog was really helpful for me. I search a lot on google to solve out this issue, finally your blog advice me to look into blocks, and i hit the tiger. Thanks a lot buddy!!!

Anonymous said...

You can also cast a variable to an array.

Original code:

The following code produces an error when $list is not an array...

foreach ($list as $key => $val) {
}

Fixed:

The (array) type cast ensures that $list is an array.

foreach ((array)$list as $key => $val) {
}

You just need to add (array) before the variable name.

Rob :)

Sean said...

Just wanted to second Rob's comment just above - type casting the array with (array) does the trick:

foreach ((array)$list as $key => $val) {
}

That makes foreach loops work in PHPtemplate templates in Drupal 7, when they otherwise wouldn't. Thanks!