The Forms API does not currently support file fields with #required => TRUE (and is documented as such in the Forms API Reference). I suggest that with a little effort it can and that to make the API more consistent and useful it should. I discovered this limitation because 4.7 flexinode allows file, image, and perhaps other file-based fields to be specified as required and attempts to impose the required-ness by setting #required => TRUE in the form element. The result is a flexinode type that cannot be created or edited because all #required file fields are always reported as not filled in, even if they are. Clearly, this is a bug in flexinode, not in the Forms API which is just behaving as specified. However, the fact that flexinode tried to work this way argues that the Forms API SHOULD support it, because it is a logical and consistent way to interpret Forms API semantics. The reason it doesn't work is that form_builder() in form.inc only looks in $_POST for values to store in $form['#value']. Since file upload data is in $_FILES, $form['#value'] is never set for file fields. When it is #required, _form_validate() reports an error. form_builder() already has a switch based on $form['#type']. We could add something like: case 'file': $form['#value'] = $_FILES['edit']['name'][$form['#key']]; break; The new $form['#value'] would then have a filename if one were uploaded or nothing if one were not. This would be sufficient to support the #required field. Since currently $form['#value'] never contains anything for file fields, storing a filename there can't hurt anybody. This requires that $form['#key'] be set so a form element knows its own name in the $_POST and $_FILES arrays. But that is easy enough to do during the recursion in form_builder(): // Recurse through all child elements. $count = 0; foreach (element_children($form) as $key) { // tell each element its own key name $form[$key]['#key'] = $key; .... } Comments? I'll implement this if the change will be accepted. Barry