title: How To Get Pydantic To Discriminate On A Field Within List[Union[TypeA, TypeB]]?
body: <p>I am trying to use Pydantic to validate a POST request payload for a Rest API. A list of applicants can contain a primary and optional other applicant. So far, I have written the following Pydantic models listed below, to try and reflect this. The Rest API json payload is using a boolean field <code>isPrimary</code> to discriminate between a primary and other applicant.</p>
  <pre class="lang-py prettyprint-override"><code>from datetime import date
  from pydantic import BaseModel, validator
  from typing import List, Literal, Optional, Union
  
  
  class PrimaryApplicant(BaseModel):
      isPrimary: Literal[True]
      dateOfBirth: Optional[date]
  
  
  class OtherApplicant(BaseModel):
      isPrimary: Literal[False]
      dateOfBirth: date
      relationshipStatus: Literal[&quot;family&quot;, &quot;friend&quot;, &quot;other&quot;, &quot;partner&quot;]
  
  
  class Application(BaseModel):
      applicants: List[Union[PrimaryApplicant, OtherApplicant]]
  
      @validator(&quot;applicants&quot;)
      def validate(
          cls,
          v: List[Union[PrimaryApplicant, OtherApplicant]]
      ) -&gt; List[Union[PrimaryApplicant, OtherApplicant]]:
  
          list_count = len(v)
          primary_count = len(
              list(
                  filter(lambda item: item.isPrimary, v)
              )
          )
          secondary_count = list_count - primary_count
  
          if primary_count &gt; 1:
              raise ValueError(&quot;Only one primary applicant required&quot;)
  
          if secondary_count &gt; 1:
              raise ValueError(&quot;Only one secondary applicant allowed&quot;)
  
          return v
  
  
  def main() -&gt; None:
      data_dict = {
          &quot;applicants&quot;: [
              {
                  &quot;isPrimary&quot;: True
              },
              {
                  &quot;isPrimary&quot;: False,
                  &quot;dateOfBirth&quot;: date(1990, 1, 15),
                  &quot;relationshipStatus&quot;: &quot;family&quot;
              },
          ]
      }
  
      _ = Application(**data_dict)
  
  
  if __name__ == &quot;__main__&quot;:
      main()
  
  </code></pre>
  <p>With the example json payload listed above, when I try to remove some of the required mandatory fields from the <code>OtherApplicant</code> payload a <code>ValidationError</code> is correctly raised. For example, if I try to remove relationshipStatus or dateOfBirth field an error is raised. However, the <code>isPrimary</code> field is also reported by Pydantic to be invalid. Pydantic believes that this the <em>isPrimary</em> field should be True??? Example Pydantic validation output is listed below.</p>
  <p>Why is Pydantic expecting that the isPrimary field should be True for an <code>OtherApplicant</code> list item in the json payload? Is it somehow associating the payload with <code>PrimaryApplicant</code> because of the use of <code>Union</code>? If so, how do I get Pydantic to use the <code>isPrimary</code> field to distinguish between primary and other applicants in the list payload?</p>
  <h1>Missing relationshipStatus field in list payload for OtherApplicant</h1>
  <pre class="lang-sh prettyprint-override"><code>pydantic.error_wrappers.ValidationError: 2 validation errors for Application
  applicants -&gt; 1 -&gt; isPrimary
    unexpected value; permitted: True (type=value_error.const; given=False; permitted=(True,))
  applicants -&gt; 1 -&gt; dateOfBirth
    field required (type=value_error.missing)
  </code></pre>
  <h1>Missing dateOfBirth field in list payload for OtherApplicant</h1>
  <pre class="lang-sh prettyprint-override"><code>pydantic.error_wrappers.ValidationError: 2 validation errors for Application
  applicants -&gt; 1 -&gt; isPrimary
    unexpected value; permitted: True (type=value_error.const; given=False; permitted=(True,))
  applicants -&gt; 1 -&gt; relationshipStatus
    field required (type=value_error.missing)
  </code></pre>