Drupal Forms - First argument is expected to be a valid callback
While creating an installation profile for Drupal based websites I lost a day tracking what should look like a small error. This seems to be often error and it seems there are many possiblities why this and similiar errors can occur:
warning: call_user_func_array() [<a href='function.call-user-func-array'>function.call-user-func-array</a>]: First argument is expected to be a valid callback, 'page_node_form' was given in /Users/bmihelac/Sites/drupal/tsitedemo/includes/form.inc on line 221.
This error occure in drupal_retrieve_form function of form.inc and means that Drupal did not found callback_function for creating $form_id form.
How Drupal retrieves form:
- drupal_retrieve_form function invokes hook_forms on all modules and statically cache returned forms
- it execute callback for given $form_id is it exists, if callback does not exists drupal_retrieve_form calls function named $form_id
- node.module defines hook_forms so every content type has form_id in format CONTENT-TYPE_node_form (page_node_type for example). Callback for all node forms is same and it is node_form. It is important to know that node_forms calls node_get_types to obtain available node types and this function statically cashes node types.
Possible solutions
In my case the error occured because I created custom node type and wanted to create nodes via drupal_execute_macro in same script. node_get_types returned caches node types and custom node was not in it. That also explains while same code worked if it was split in two scripts. Once the problem is found, solution is easy as reloading node types:
node_get_types(‘types’, NULL, TRUE);
If you have similiar problems you can:
- check if you can retrieve form with drupal_retrieve_form($form_id)
- check if $form_id is created in module_invoke_all(‘forms’)
- check if module that should create form is loaded with module_list(FALSE, TRUE, FALSE)
Thanks for reading and hope this will save you some time.
UPDATE: I noticed that some other functions statically cache variables so similiar problems occured when creating multilanguage nodes. The best solution for now seems to create content types, blocks, etc in installation profile and create content in other script.
I am Bojan Mihelac and this blog is dedicated to share code, thoughts, tools and advices I came up with while working at
blog comments powered by Disqus