Index: modules/field/field.form.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.form.inc,v
retrieving revision 1.23
diff -u -r1.23 field.form.inc
--- modules/field/field.form.inc	27 Aug 2009 04:40:12 -0000	1.23
+++ modules/field/field.form.inc	28 Aug 2009 03:12:50 -0000
@@ -196,7 +196,8 @@
         '#name' => $field_name . '_add_more',
         '#value' => t('Add another item'),
         '#attributes' => array('class' => array('field-add-more-submit')),
-        // Submit callback for disabled JavaScript.
+        '#validate' => array(),
+        '#validate_section' => array($field_name),
         '#submit' => array('field_add_more_submit'),
         '#ajax' => array(
           'callback' => 'field_add_more_js',
Index: modules/poll/poll.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.module,v
retrieving revision 1.310
diff -u -r1.310 poll.module
--- modules/poll/poll.module	24 Aug 2009 00:14:21 -0000	1.310
+++ modules/poll/poll.module	28 Aug 2009 03:12:50 -0000
@@ -279,7 +279,9 @@
     '#value' => t('More choices'),
     '#description' => t("If the amount of boxes above isn't enough, click here to add more choices."),
     '#weight' => 1,
-    '#submit' => array('poll_more_choices_submit'), // If no javascript action.
+    '#validate' => array(),
+    '#validate_section' => array('choice_wrapper'),
+    '#submit' => array('poll_more_choices_submit'),
     '#ajax' => array(
       'callback' => 'poll_choice_js',
       'wrapper' => 'poll-choices',
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.367
diff -u -r1.367 form.inc
--- includes/form.inc	27 Aug 2009 04:40:12 -0000	1.367
+++ includes/form.inc	28 Aug 2009 03:12:50 -0000
@@ -787,7 +787,7 @@
       // A simple call to empty() will not cut it here as some fields, like
       // checkboxes, can return a valid value of '0'. Instead, check the
       // length if it's a string, and the item count if it's an array.
-      if ($elements['#required'] && (!count($elements['#value']) || (is_string($elements['#value']) && strlen(trim($elements['#value'])) == 0))) {
+      if ($elements['#required'] && !_form_validate_skip($elements, $form_state) && (!count($elements['#value']) || (is_string($elements['#value']) && strlen(trim($elements['#value'])) == 0))) {
         form_error($elements, $t('!name field is required.', array('!name' => $elements['#title'])));
       }
 
@@ -825,7 +825,7 @@
     }
     // Call any element-specific validators. These must act on the element
     // #value data.
-    elseif (isset($elements['#element_validate'])) {
+    elseif (isset($elements['#element_validate']) && !_form_validate_skip($elements, $form_state)) {
       foreach ($elements['#element_validate'] as $function) {
         if (function_exists($function))  {
           $function($elements, $form_state, $form_state['complete form']);
@@ -837,6 +837,36 @@
 }
 
 /**
+ * Check if an element's validation should be skipped.
+ *
+ * This is used to skip #required and #element_validate properties but never
+ * properties that should be enforced by HTML, such as #maxlength or #options.
+ *
+ * @param $element
+ *   The element whose parents will be checked to determine if this element's
+ *   validation should be skipped.
+ * @param $form_state
+ *   The form state. The 'clicked_button' property will be checked to determine
+ *   which elements should be validated.
+ * @return
+ *   Boolean TRUE if the element should not be validated. FALSE if the element
+ *   should be validated.
+ */
+function _form_validate_skip($element, $form_state) {
+  $skip = FALSE;
+  if (isset($form_state['clicked_button']['#validate_section'])) {
+    $parents = $form_state['clicked_button']['#validate_section'];
+    foreach ($parents as $key => $parent) {
+      if ($element['#parents'][$key] != $parent) {
+        $skip = TRUE;
+        break;
+      }
+    }
+  }
+  return $skip;
+}
+
+/**
  * A helper function used to execute custom validation and submission
  * handlers for a given form. Button-specific handlers are checked
  * first. If none exist, the function falls back to form-level handlers.
