Does $element['#title'] need to be escaped with check_plain()? I see (with grep) that the value of $element['#title'] in a render element is sometimes sanitized with check_plain(), and sometimes printed unfiltered.

Which one is correct? Is the value considered safe to print? Or does it depend on the theme hook?

Examples from core:

modules/field/field.form.inc
314:        'data' =&gt; '&lt;label&gt;' . t('!title !required', array('!title' =&gt; $element['#title'], '!required' =&gt; $required)) . "&lt;/label&gt;",


(notice the "!" in the placeholder, this means that format_string() will not escape the placeholder value)

modules/field/field.module
1052:  $variables['label'] = $variables['label_hidden'] ? NULL : check_plain($element['#title']);


This question applies in both ways:


When setting $element['#title'] in a render element.
When printing the value of $element['#title'].
When printing a $variables['title'] value that was extracted from a render element property.


Note: Very often the $element['#title'] property comes directly from a t() call.
It's user input and should be considered unsafe; you should always sanitise it.

For the specific example you've given where it isn't, the title is already sanitised before it's passed to the theme function containing the t() call. This happens in field_multiple_value_form()

$title = check_plain($instance['label']);

...

$element = array(
  ...
  '#title' =&gt; $multiple ? '' : $title,
  ...
);


As an aside, if you ever did need to preserve HTML in the title for whatever reason, you could consider using filter_xss() instead.