After a messy Drupal 6 upgrade, I'm getting the following error when cron.php is run:

Invalid argument supplied for foreach() in /var/www/vhosts/[site]/httpdocs/modules/taxonomy/taxonomy.module on line 1188.

I've found similar errors in the Drupal forums and on the web, but none seem to fit my situation. Any thoughts?

Comments

grobemo’s picture

John,

I've been having the same problem, along with similar problems relating to CCK. (See, e.g., http://drupal.org/node/237585 and the links from there to similar issues.)

In general, these warnings arise when an incomplete node object is passed into a function. In this case in particular, nodes are sometimes passed to taxonomy_node_update_index() without $node->taxonomy, so the function gets upset when it looks for that property.

The only way I know of to get rid of this problem (for now) is to hack core. Add this code to the beginning of taxonomy_node_update_index():

  if (empty($node->taxonomy)) {
    return;
  }

This exits the function if the node doesn't have the taxonomy property.

If you're using Drupal 6.2. (with taxonomy.module v. 1.414.2.1), your taxonomy_node_update_index() should now look like this:

function taxonomy_node_update_index(&$node) {
  if (empty($node->taxonomy)) {
    return;
  }
  
  $output = array();
  foreach ($node->taxonomy as $term) {
    $output[] = $term->name;
  }
  if (count($output)) {
    return '<strong>('. implode(', ', $output) .')</strong>';
  }
}

Maybe this is an issue for the serious developers to explore a bit?

bradleywebhome’s picture

Thank you! That modification worked exactly as you said it would. My symptoms were the same and your resolution seems to be right on.

Rob T’s picture

I'm giving this a go as well. Thanks for the tip.

stefgosselin’s picture

Stumbled on this thread after an hour of debugging, I had already figured that drupal_cron_run timed out, followed the trail to the search indexer, and that led me to taxonomy module, choking on taxonomy_update_node_index, as noted above.

The posted fix works fine, I wish I'd of seen this thread BEFOREHAND. How about someone submit it as a patch, save others the pain of it all.
Anyhow, thanks David for the post, very much appreciated sir.

I have yet to see any problem, however complicated, which, when looked
at in the right way, did not become still more complicated.
-- Poul Anderson

dinis’s picture

Thank you :)

An unbelieveably simple fix which put a work-around in place that solved an issue I've been fighting with for weeks.

As a slight aside, is there any way to actually see which cotent / node is triggering the error? Maybe even a bodge to echo the nid of the node just before exiting the fuction? My thinking is one could then list all the content with incomplete taxonomy properties, fix them, and remove the core patch when it's all complete.

I'll experiment myself a little later.

Kind regards,
Danielle

loko’s picture

Thank You:)

JJustian132’s picture

Could you avoid the hack by changing the PHP error level? Just curious. Thanks.

petermilad’s picture

Thanks a lot grobemo
your code is working for me.

Peter Aziz

jasonabc’s picture

Hate hacking core, but it works - thanks for posting.

computer_jin’s picture

Hi every one ,
I am also having this same issue before many days and today i debub how can i solve this issue actually i was having error ....
warning: Invalid argument supplied for foreach() in \includes\form.inc on line 1193.
I am having this issue and when i debug and comment the code of checkboxes in my module than this error is resolved but i have to use this checkboxes ,check my code if i m missing some minor code and tell me how can i solve this ..

$form['payment_options']['business_payment_method']= array(
'#type' => 'checkboxes',
'#title'=> t('Payment Options'),
'#default_value' => variable_get('business_payment_method',$selected_payment),
'#options' => $payment_options,
);
I am using this tell me if you understand how can i solve this issue ...

Thanks in Advance

Azhar
4 Ace Technologies(www.4acetech.com)
karachi,Pakistan

--
Azhar uddin
Technical Lead
email : engr.azharuddin@gmail.com
skype : computer_jin

pwolanin’s picture

---
Work: BioRAFT

aharown07’s picture

Sorry for all the emoting but I was up half the night trying to figure out if this error was serious or not and how to fix it... disabling modules, rerunning cron, etc., repeat, etc.

In may case, imported a bunch of nodes from wordpress (using wordpress import module) and also a bunch from vbulletin (using vbtodrupal module) and some of these apparently are not quite all intact w/respect to taxonomy so... but I'm guessing.

Anyway, this fix works great.

chrism2671’s picture

I would like to second this- we have the same problems on nodes that were imported from vbulletin.

skor’s picture

I'm getting this, after having changed some nodes from one type to another, using an sql command.

So I took the above code one step further, and did this:

  if (empty($node->taxonomy)) {
    $bad_nid = $node->nid;
    printf('Node %d is broken, ',$bad_nid);
    return;
  }

Then I went an ran cron.php and I get a list of the nodes that have a problem. I have about 35-40 of them, and I could go edit them manually.

Then I tried adding print_r (and dprint_r from the devel module) to take a look at what was different about those nodes. I'm thinking maybe just pick a node of similar type and copy its taxonomy structure over to each of these broken nodes.

Any thoughts on how to do that?

aharown07’s picture

...sort of. I eventually abandoned the hack because the messed up nodes were causing other, even more serious, problems. So I didn't really clean up the data, I just flushed it by returning to a clean backup.

It would be great tool if someone could put skor's code, along w/the "what's different" functionality into a module of some kind. This would allow developers of import modules like wordpress to drupal and vbulletin to drupal to troubleshoot import issues and look for ways around them.

skor’s picture

using the devel module's dprint_r, here's what a the taxonomy structure looks like for a 'good' node on my site:

    [taxonomy] => Array
        (
            [1] => stdClass Object
                (
                    [tid] => 1
                    [vid] => 1
                    [name] => Site Config
                    [description] => Notes on the configuration of this site
                    [weight] => 4
                )

        )

Here's what it looks like for a 'broken' node:

    [taxonomy] => Array
        (
        )

So I edited one of the nodes that had an empty taxonomy array, entered a term, and saved it. No change to the structure. Not sure where it's getting saved if not there, but the term was saved somewhere.

Next, I tried dis-associating the node type and the vocabulary, but that didn't help. Then I re-assigned it again, hoping that would re-initialize all the taxonomy storage. Still no luck.

skor’s picture

So does anyone know where I can find some documentation on where in the database the taxonomy terms are associated with a particular node? I'd like to see if I can figure out how to copy the taxonomy attributes of a good node over the attributes of a broken node.

grobemo’s picture

I think the magic happens in taxonomy_node_get_terms when it gets called from taxonomy_nodeapi.

gilgabar’s picture

The table 'term_node' is the one that associates terms with nodes. The table 'term_data' holds the data about each term.

I tried running the snippet to print a list of problem nodes and ended up with 'node 0 is broken' thirteen times. Anyone have any insight into what that might mean? I usually get thirteen instances of the foreach() message whenever cron is run, so that part isn't a mystery. I'm not really sure what to make of the node id of zero though.

skor’s picture

Sorry, not sure about that.

I don't think there is a node zero. All my sites start at node #1.

Aleet’s picture

Hello,

I tried the above solution and cron run displayed:

Node 1 is broken, Node 2 is broken, Node 3 is broken,

That's every node in my new site on 6.13. Everyone of those node is a sitenote content type.

I did not any taxnomy created for sitenotes. Once I associated each of the three nodes with a term, the errors went away.

Don't have time to research this further. IF anyone finds out more please post.

review:

I changed following

To change starting with line 1212 of taxonomy.module, drupal 6.13

function taxonomy_node_update_index(&$node) {
  $output = array();
  foreach ($node->taxonomy as $term) {
    $output[] = $term->name;
  }
  if (count($output)) {
    return '<strong>('. implode(', ', $output) .')</strong>';
  }
}

to this:

function taxonomy_node_update_index(&$node) {
  if (empty($node->taxonomy)) {
    $bad_nid = $node->nid;
    printf('Node %d is broken, ',$bad_nid);
    return;
  }
 
  $output = array();
  foreach ($node->taxonomy as $term) {
    $output[] = $term->name;
  }
  if (count($output)) {
    return '<strong>('. implode(', ', $output) .')</strong>';
  }
}

And then back again to original code once I figured having a term on my nodes solves the issue.

skor’s picture

I had assumed that they were broken because I had originally entered them as admin blog posts, and then at some point changed their content type from blog to sitenote. Now I think I should go in and check if there are any broken node that didn't get converted.

skor’s picture

No time to investigate right now, but here's a code snippet that could be customized to find & fix the nodes:

http://drewish.com/node/139

Just posting here in case anyone else wants to take a look, or in case I get some time next month.

davidhk’s picture

I had the same 'Invalid argument supplied for foreach() ...' message described above, but when I added the debug lines to taxonomy_node_update_index, it just showed:

Node 0 is broken, Node 0 is broken,

The other symptom was a record in the search_dataset table with sid=0, but no corresponding record in the node table with nid=0.

By also adding a debug print at the start of _node_index_node in node.module, I could see which nodes were causing the errors. They seemed like problem nodes from a long way back, with no matching entries in node_revisions, so I was able to delete them, and the sid=0 record from search_dataset. It all seems ok now.

So the source of the problem in this case was corrupted nodes, made worse by the fact that in _node_index_node, there is no check to see if the first line's call to node_load is successful.

gilgabar’s picture

Thanks mrb, that solved the problem finding my own corrupt node 0 nodes.

abi’s picture

can you pls tell me how did you solve this working from last 5 hours on this issue.. need you r help .. pls reply back with all steps to took to solve this.

abi

gilgabar’s picture

To find the problem nodes:

  • open up /modules/node/node.module
  • find the function called _node_index_node
  • add print_r($node); to the top of that function
  • save the file
  • run cron
  • It should print a list of node ids

Edit your database with phpMyAdmin or something similar and fix or delete the problem nodes. Remove the code you added above and that should be it.

ggevalt’s picture

... Node 0 is broken, Node 0 is broken, Node 0 is broken, Node 0 is broken, Node 0 is broken, Node 0 is broken, Node 0 is broken, Node 0 is broken,
It only ran for one line.

Any thoughts as to what this means? I do not have a node 0 in the database.

thanks

geoff

gilgabar’s picture

If you implemented skor's code above in taxonomy.module you may need to disable it in order to see the results from adding print_r($node); to node.module.

v3lkov3r’s picture

I was having

Invalid argument supplied for foreach() in ../modules/taxonomy/taxonomy.module on line 1226

showing up after each cron run

The procedure above gave me the node id that was causing the issue, a few quick edits in phpMyAdmin, and problem was solved
(bad UserID in my case)

Thanks!!

Anonymous’s picture

I had the same result. node 0, node 0, node 0, along with access denied. Removing all Quiz Multi-choice pages solved the problem. Quiz is under development, but I haven't been installing any of the beta versions. Anyway, that turned out to be the problem module for me. No idea why the nid was returning 0. If you read this (I realize it's an old thread) let me know if you were also using Quiz.

Ryan Palmer’s picture

I had this issue as well, and discovered node_load() was not returning a valid node because the INNER JOIN on the users table prevents the loading of nodes without a valid user record in the users table.

It's important to set the node author uid to 0 (zero) so the node table record can be joined with the uid = 0 users record.

Run the following query to see if you have this same issue:

SELECT n.nid, n.uid AS original_n_uid, u.uid FROM node n LEFT JOIN users u ON n.uid = u.uid WHERE u.uid IS NULL;

biohabit’s picture

That SQL statement saved me quite a bit of time!

Shai’s picture

Thanks Ryan for that SQL. That provided the info on 11 nodes whose node.uid was a uid that from a deleted user. I had upgraded a system from 4.5.5 to 6.14 so I'm not surprised I ran into something like this. But that SQL and this thread in general saved a load of troubleshooting time on my part.

The nodes returned page-not-found when trying to access them via UI. But simply going into the node table in the db and setting the node.uid to a uid that exists on the users table completely fixed the problem.

For others, note that I did not need to attempt any of the other fixes mentioned on this thread. Those other fixes, of course, may still apply in your situation. However, you may want to try running the SQL mentioned here first because if the problem is reference to a non-existent user, then you can fix your problem without touching your code at all.

Thanks much,

Shai

gilgabar’s picture

I put together a simple module for my own use to deal with the issue, based on Ryan's approach above, and I thought I would share. It lists all the broken nodes in a table and gives you the option to set the uid to zero or delete the nodes entirely if that's more appropriate in your situation. So if you are either unable or unwilling to edit your database directly you may find this helpful. It goes without saying, but use at your own risk, make backups, etc.

nodeuidcleanup.zip

hyperlogos’s picture

So either I have another problem, or your tool doesn't work on 6.20 :)

squeakyn’s picture

Your node uid cleanup module worked perfectly, thank you!

mersoy’s picture

Thank you very much. Got rid of a big problem.

panigrc’s picture

Thanx it worked for me too !

Ryan Palmer’s picture

Glad it helped!

stuen93’s picture

I ran into a similar issue on two of our sites and the sql query along with using phpMyAdmin to fix the nodes took care of it.

cgrant3d’s picture

Thanks Ryan, that worked perfectly! This problem was causing errors with taxonomy and devel on my d5->d6 site I'm upgrading... Thank you very much!

Chris

Anonymous’s picture

Thanks very much Ryan. An elegant solution to a niggling problem that had been caused by using an import module to try to capture static pages.

span’s picture

You are a hero for all us non-experts Drupalers that ran into this problem.

My original issue was with the search module not indexing properly when Cron was run and i started getting these errors on searches. It turned out i had some 400 rows that had been created but what I assume to be spam bots that somehow had managed to get node input with invalid uid's'.

Thanks.

jmav’s picture

Problem appeared when i upgraded from 5.19 -> 6.13.

I used function:

  if (empty($node->taxonomy)) {
    $bad_nid = $node->nid;
    printf('Node %d is broken, ',$bad_nid);
    return;
  }

return "node 0", so i opened table node and searched for 0 in VID column (not NID !!!) and deleted it.
I remembered that i had problem with this node in the past, node type was from simplenews module.

REMEMBER: backup database !!!

guusbosman’s picture

Thanks for this debugging information; it helped me find a broken node on my site.

In my case, I had an entry in table node, but no corresponding entry in table node_revisions. To found out which nid was the culprit, I slightly changed the function. I needed access to the original $node that was passed to the function since node_load was failing:

function _node_index_node($node) {
  $x=$node;
  $node = node_load($node->nid);
  if (empty($node->taxonomy)) {
    print_r($x); // prints information on the $node that was originally passed to this function
    $bad_nid = $node->nid;
    printf('Node %d is broken, ',$bad_nid);
    return;
  }
...
}
r_honey’s picture

I always get this error:
Invalid argument supplied for foreach() in taxonomy.module on line 1214.

during cron run. I had not done anything like importing or something like that to break taxonomy.

As suggested above, I printed all node ids. To my surprise, all node ids belonged to nodes created by multichoice question module (installed with the quiz module). There was exactly 1 error for each multichoice question node.

Although I have incorporated the check for empty() to avoid this error, can somebody tell me what is the exact problem with the multichoice module causing this error??

r_honey’s picture

I wonder despite so many replies to this thread, no one else has faced this issue as I have faced it, related to the multichoice question module associated with the quiz module.

I could not figure out why all multichoice question nodes triggered this problem on cron run!!!

fredklopper’s picture

I'm facing the same problems. Check this: http://drupal.org/node/536116

Update: Never mind. I did no see your post #7.

With regards,

Fred Klopper

Stephen Winters’s picture

I also get this "taxonomy.module on line 1214." error whenever I run cron. My website doesn't have the quiz module and I'm still trying to figure out the cause. I tried gilgabar's nodeuidcleanup.zip module, and it said "There are no broken nodes to fix." Please let me know if anyone finds a fix to this error. Thanks

Best Wishes,
Stephen

posterx’s picture

Thank you very much!
That helped me!

<?php
function _node_index_node($node) {
  $x=$node;
  $node = node_load($node->nid);
  if (empty($node->taxonomy)) {
    print_r($x); // prints information on the $node that was originally passed to this function
    $bad_nid = $node->nid;
    printf('Node %d is broken, ',$bad_nid);
    return;
  }
...
}

?>

Stephen Winters’s picture

subscribe

Adam S’s picture

I am getting this error after I installed the subscription.module. Any ideas?

Breakerandi’s picture

subscribe

Drupal User Group Munich

marcushenningsen’s picture

subscribing

TimG1’s picture

subscribing

Ainur’s picture

I think that adding additional checks to taxonomy_node_update_index is not a good solution. For example checks mentioned here by grobemo worked for me, in sense, error notice dissappeared, but cron couldn't index anything getting stuck with couple of nodes.
First of all I've tried to debug taxonomy_node_update_index logging stacked nodes, and found, that $node variable is empty in my case, so I had to debug function calling to taxonomy_node_update_index in node.module node_update_index.
When i got a list of nodes i tried to load'em visiting relative urls, founding Drupal always outputs 404.
The problem was missing users in users table and unupdated node table where delete user uid should be replaced with 0 (anonymous user), selecting nodes with non-existent users with this query:
SELECT uid FROM node WHERE uid NOT IN (SELECT DISTINCT uid FROM users)
and setting them to uid 0, seems to resolve the problem for me.
This problem emerged only after 5.x > 6.x update, and because my site was running phpBB in early 2003 where this users were deleted.

missym’s picture

Yeah - bad idea to hack the core. Worse idea to have a broken site. Anyway, thanks for this sweet bit of code:

SELECT n.nid, n.uid AS original_n_uid, u.uid FROM node n LEFT JOIN users u ON n.uid = u.uid WHERE u.uid IS NULL;

Fixed the data, life is better. The problem was with profile nodes that weren't being deleted in my custom module - totally my bad.

Ainur’s picture

I'm glad I was able to help.

I've found, that this problem can reappear if you have nodes in node table without relative revisions.

gateway69’s picture

I have also been tracking down this problem lately, It turns out some of the code im using in custom modules are causing duplicate nid's for some tables, also the revisions seem to be out of whack and owned by user 0.. I get this

Warning: Invalid argument supplied for foreach() in taxonomy_node_update_index()

Issues when I have dup nodes for cck content types mainly, and somehow my revisions are out of sync..

question,

is their a way to get revisions back to sync with everything, usually on other drupal sites the nid = vid for me and it never changes.

using node_save to update a node with the nid, seems to fail or cause a dup node to be created when you also dont pass the proper revision id along with it, as stated above usually nid for me = vid so that wasnt ever an issue..

does node save need the rev id to update a node ?

zyxware’s picture

Here are some SQL queries to find bad data. Hope this helps

select n.nid from node n left join users u on n.uid=u.uid where u.uid is null
select n.nid from node n left join node_revisions nr on n.vid=nr.vid where nr.vid is null
select nr.vid from node_revisions nr left join node n on nr.nid=n.nid where n.nid is null
select * from term_node where nid = 0 or vid = 0
select t.nid from term_node t left join node n on t.nid = n.nid where n.nid is null
select t.nid from term_node t left join node_revisions nr on t.nid = nr.nid and t.vid = nr.vid where nr.vid is null
yngens’s picture

very useful commands, thanks

slicedsoup’s picture

The suggestion from Ainur above of setting all of the nodes with uid's that are not in the user table to zero has worked for me, 100 errors down to 2, just need to track them down now.

ashraf.hussain’s picture

Thanks the code helped me too..a single node was causing the problem for me...after I deleted that code, did not receive that error again.

<?php
function _node_index_node($node) {
$x=$node;
$node = node_load($node->nid);
if (empty($node->taxonomy)) {
print_r($x); // prints information on the $node that was originally passed to this function
$bad_nid = $node->nid;
printf('Node %d is broken, ',$bad_nid);
return;
}
...
}