When creating a new user, I got this error:

An illegal choice has been detected. Please contact the site administrator.

I'm sure I entered all the required information. This is when I am logged-in as administrator.
I'm using drupal 7.10.

I have a few lines of code in my hook_form_alter() which alters the user registration form :

if($form_id == 'user_register_form'){
    $form['profile_main']['#weight'] = 10; 
    # Password and Confirm password
    $form['account']['pass']['#weight'] = -9; # move above E-mail address
    # User role
    $form['autoassignrole_user']['#weight'] = 2;
    $form['autoassignrole_user']['user_roles']['#attributes'] = array('onclick' => "Drupal.mymodule.toggleProfile(this)");
    if(in_array('administrator', $user->roles)){ # if master administrator, hide it
        $form['autoassignrole_user']['#required'] = FALSE;
        $form['autoassignrole_user']['#type'] = 'hidden';           
elseif($form_id == 'user_profile_form'){
    if(!in_array('administrator', $user->roles)){ # if not administrator
        $elems[] = 'timezone';
        $form['timezone']['#required'] = FALSE;
        $form['timezone']['#type'] = 'hidden';          
  • Are you doing anything with javascript/ajax on the form?
    – Clive
    Commented Feb 4, 2012 at 3:17
  • Have you implemented hook_form_alter() anywhere, or enabled a module that modifies the user creation form?
    – Citricguy
    Commented Feb 4, 2012 at 4:13
  • Yes, I have hook_form_alter(). I updated my original post.
    – Sithu
    Commented Feb 4, 2012 at 4:49

3 Answers 3


When you submit a form Drupal checks the integrity of it, i.e. it checks that the submitted values fall in line with the list of possible values for each element in the original form definition.

So, if you've got a select/checkboxes/radio buttons element on the form and you change the possible options for this using javascript on the client side, the new options won't match up with the ones Drupal knew about when the form was built. In this instance Drupal will rightly inform the user "An illegal choice has been detected.", because it has. This is an excellent security feature and is the default behaviour. It can't be switched off without some serious effort.

I would take a guess in your case that this problem is happening in the JS you're attaching to the autoassignrole_user element.

If you want to change a form's structure using JS you need to do it the 'Drupal' way, using AJAX to update the form on the server-side:

function MYMODULE_my_form($form, &$form_state) {
  // If the checkbox is ticked, load one set of options
  if (isset($form_state['values']['check']) && $form_state['values']['check']) {
    $options = new_options();
  else {
    // Otherwise load the default options
    $options = default_options();

  $form['check'] = array(
    '#type' => 'checkbox',
    '#title' => 'Click to change options',
    '#default_value' => isset($form_state['values']['check']) ? $form_state['values']['check'] : 1,
    '#ajax' => array(
      'wrapper' => 'options-wrapper',
      'callback' => 'my_form_ajax_callback'

  $form['options'] = array(
    '#type' => 'select',
    '#title' => 'Options',
    '#options' => $options,
    '#prefix' => '<div id="options-wrapper">',
    '#suffix' => '</div>'

function my_form_ajax_callback(&$form, &$form_state) {
  // Return the options element which will have been changed in the re-build of the form
  return $form['options'];

The above is a very simple AJAX example that uses a checkbox change event to change the values in a select list on the form. Doing it this way will keep the internal structure of the form intact and you will no longer get the error message you're currently getting.

Have a look at the Form API documentation and AJAX framework documentation for a lot more information on this.


I think the error is most likely generated when I changed radio selection to hidden type. $form['autoassignrole_user']['#type'] = 'hidden';
I often used the type hidden when I want to hide a particular field on the form. It seems it cannot be done for check boxes and radios.

The main problem is that I had to use Auto Assign Role module to allow the end user the option of choosing their own role ( with radios ) on user registration. This duplicates user role selection for administrator. Drupal core provides a role selection with check boxes, whereas Auto Assign Role adds role selection with radios. Thus, I tried to hide Auto Assign Role for administrator, then I got the error.

Actually, as I don't want check boxes for role selection, I changed my mind to hide Drupal core role selection and raised Auto Assign Role. Here is my steps :

  1. Hide the check boxes by wrapping a DIV as I cannot use ['#type'] = 'hidden' which would generate the error.
  2. Although they are hidden on the form visually, leaving them unchecked would generate the same error. Why Drupal don't make them required instead of issuing this security error ? Authenticated user role is checked by default, but it would not be in the POST array as it is default-disabled.
  3. Thus, I created a javacript function to check the associated user role upon a role selection of Auto Assign Role.

This put the error away. Here is some code snippets of hook_form_alter() :

    # Roles ( Drupal core user roles check boxes )
    $form['account']['roles']['#prefix'] = '<div style="display:none">';
    $form['account']['roles']['#suffix'] = '</div>';
    # Auto Assign Role ( user roles radios )
    $form['autoassignrole_user']['#weight'] = 2;
    $form['autoassignrole_user']['user_roles']['#attributes'] = array('onclick' => "Drupal.mymodule.toggleProfile(this)");

Here is javascript code snippet :

        $('#edit-roles input[type=checkbox]').each( function(i, elem){
            if(elem.disabled == false){
        $('#edit-roles-'+$(obj).val()).attr('checked', 'checked');

Drupal checks the option values before submitting values to the database. Its check it with the option values which was there when form was created. Its a security measure od drupal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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