How to deal with PHP Fatal error: Cannot unset string offsets in field.default.inc when implementing custom widget? I have a custom auto-complete widget that I use to create a custom field that is used to create a custom content type in a custom module.

I have hook_field_widget_info

function MODULE_field_widget_info()
{
    return array(
        "MODULE_taxonomy_autocomplete" =&gt; array(
            "label"         =&gt; t("MODULE Autocomplete term widget (tagging)"),
            "field types"   =&gt; array("taxonomy_term_reference"),
            "settings"      =&gt; array(
                "size"              =&gt; 60,
                "autocomplete_path" =&gt; "taxonomy/autocomplete",
            ),
            "behaviors"     =&gt; array(
                "multiple values"   =&gt; FIELD_CARDINALITY_UNLIMITED,
            ),
        ),
    );
}


I have hook_field_widget_form

function MODULE_field_widget_form(&amp;$form, &amp;$form_state, $field, $instance, $langcode, $items, $delta, $element)
{
    $tags = array();
    foreach ($items as $item)
    {
        $tags[$item["tid"]] = isset($item["taxonomy_term"]) ? $item["taxonomy_term"] : taxonomy_term_load($item["tid"]);
    }

    $element += array(
        "#type"                 =&gt; "textfield",
        "#default_value"        =&gt; taxonomy_implode_tags($tags),
        "#autocomplete_path"    =&gt; $instance["widget"]["settings"]["autocomplete_path"] . "/" . $field["field_name"],
        "#size"                 =&gt; $instance["widget"]["settings"]["size"],
        "#maxlength"            =&gt; 1024,
    );

    return $element;
}


I have hook_field_widget_error

function MODULE_field_widget_error($element, $error, $form, &amp;$form_state)
{
    form_error($element, $error["message"]);
}


Here I am creating the field of the content type

field_create_field(
    array(
        "field_name"    =&gt; "field_MODULE_tags",
        "type"          =&gt; "taxonomy_term_reference",
        "bundles"       =&gt; array(
            "node" =&gt; array(
                "CONTENT_TYPE",
            ),
        ),
        "cardinality"   =&gt; "-1",
        "settings"      =&gt; array(
            "allowed_values" =&gt; array(
                array(
                    "vocabulary" =&gt; "TAXONOMY_LIST",
                    "parent"     =&gt; 0,
                ),
            ),
        ),
    )
);

field_create_instance(
    array(
        "field_name"    =&gt; "field_MODULE_tags",
        "entity_type"   =&gt; "node",
        "label"         =&gt; "Tags",
        "description"   =&gt; "",
        "bundle"        =&gt; "CONTENT_TYPE",
        "widget"        =&gt; array(
            "weight"    =&gt; 1,
            "type"      =&gt; "MODULE_taxonomy_autocomplete",
            "settings"  =&gt; array(
                "size"              =&gt; 60,
                "autocomplete_path" =&gt; "taxonomy/autocomplete",
            ),
        ),
    )
);


All of this appears to work fine, the content type shows the correct field, the auto complete works great, but when I try to save a new node of the custom type, I get the following error:

PHP Fatal error:  Cannot unset string offsets in /modules/field/field.default.inc on line 41


If I look at field.default.inc file I see

function field_default_extract_form_values($entity_type, $entity, $field, $instance, $langcode, &amp;$items, $form, &amp;$form_state) {
  $path = array_merge($form['#parents'], array($field['field_name'], $langcode));
  $key_exists = NULL;
  $values = drupal_array_get_nested_value($form_state['values'], $path, $key_exists);
  if ($key_exists) {
    // Remove the 'value' of the 'add more' button.
    unset($values['add_more']);
    $items = $values;
  }
}


where line 41 is unset($values['add_more']);

If I output $values, I get a string where unset is expecting an array.

How can I make my value an array?

I've tried using hook_form_alter to add a custom submit function so I can manipulate the value but the custom submit never gets fired (which is weird).
hook_node_validate was how I was able to fix this issue.

function MODULE_node_validate($node, $form, &amp;$form_state)
{
    foreach ($form as $field =&gt; $field_data)
    {
        $field_info    = field_info_field($field);
        $instance_info = field_info_instance("node", $field, "CONTENT_TYPE");

        // since this field returns a string when an array is required, we need to correct
        // the data here before it goes any further.
        if ($instance_info["widget"]["type"] == "MODULE_taxonomy_autocomplete")
        {
            // Recieved: string
            // Expecting: array(array("tid" =&gt; TID),)
            $tag_names = explode(",", $form_state["values"][$field][$node-&gt;language]);
            $form_state["values"][$field][$node-&gt;language] = array();
            foreach ($tag_names as $tag)
            {
                $term = taxonomy_get_term_by_name($tag, $field_info["settings"]["allowed_values"][0]["vocabulary"]);
                $term = array_shift($term);

                $form_state["values"][$field][$node-&gt;language][] = array("tid" =&gt; $term-&gt;tid);
            }
        }
    }
}