<h3 dir="auto">First Check</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I added a very descriptive title to this issue.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I used the GitHub search to find a similar issue and didn't find it.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I searched the FastAPI documentation, with the integrated search.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already searched in Google "How to X in FastAPI" and didn't find any information.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already read and followed all the tutorial in the docs and didn't find an answer.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/samuelcolvin/pydantic">Pydantic</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/swagger-api/swagger-ui">Swagger UI</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/Redocly/redoc">ReDoc</a>.</li>
</ul>
<h3 dir="auto">Commit to Help</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I commit to help with one of those options <g-emoji class="g-emoji" alias="point_up_2" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f446.png">👆</g-emoji></li>
</ul>
<h3 dir="auto">Example Code</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from pydantic import BaseModel
from fastapi import FastAPI

from typing import Tuple

class FooModel(BaseModel):
  prop: Tuple[int, str]


app = FastAPI()

@app.get('/', response_model=FooModel)
def get_foo():
 return {&quot;prop&quot;: (0, 'ok')}

print(app.openapi())"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">pydantic</span> <span class="pl-k">import</span> <span class="pl-v">BaseModel</span>
<span class="pl-k">from</span> <span class="pl-s1">fastapi</span> <span class="pl-k">import</span> <span class="pl-v">FastAPI</span>

<span class="pl-k">from</span> <span class="pl-s1">typing</span> <span class="pl-k">import</span> <span class="pl-v">Tuple</span>

<span class="pl-k">class</span> <span class="pl-v">FooModel</span>(<span class="pl-v">BaseModel</span>):
  <span class="pl-s1">prop</span>: <span class="pl-v">Tuple</span>[<span class="pl-s1">int</span>, <span class="pl-s1">str</span>]


<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</span>()

<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">get</span>(<span class="pl-s">'/'</span>, <span class="pl-s1">response_model</span><span class="pl-c1">=</span><span class="pl-v">FooModel</span>)</span>
<span class="pl-k">def</span> <span class="pl-en">get_foo</span>():
 <span class="pl-k">return</span> {<span class="pl-s">"prop"</span>: (<span class="pl-c1">0</span>, <span class="pl-s">'ok'</span>)}

<span class="pl-en">print</span>(<span class="pl-s1">app</span>.<span class="pl-en">openapi</span>())</pre></div>
<h3 dir="auto">Description</h3>
<h2 dir="auto">Summary</h2>
<p dir="auto">The above code must be failed with a ValidationError like this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Traceback (most recent call last):
  File &quot;&lt;pyshell#3&gt;&quot;, line 1, in &lt;module&gt;
    a()
  File &quot;&lt;pyshell#1&gt;&quot;, line 17, in a
    print(app.openapi())
  File &quot;/usr/local/lib/python39/lib/site-packages/fastapi/applications.py&quot;, line 136, in openapi
    self.openapi_schema = get_openapi(
  File &quot;/usr/local/lib/python39/lib/site-packages/fastapi/openapi/utils.py&quot;, line 410, in get_openapi
    return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True)  # type: ignore
  File &quot;pydantic/main.py&quot;, line 406, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 2 validation errors for OpenAPI
components -&gt; schemas -&gt; FooModel -&gt; properties -&gt; prop -&gt; items
  value is not a valid dict (type=type_error.dict)
components -&gt; schemas -&gt; FooModel -&gt; $ref
  field required (type=value_error.missing)"><pre class="notranslate"><code class="notranslate">Traceback (most recent call last):
  File "&lt;pyshell#3&gt;", line 1, in &lt;module&gt;
    a()
  File "&lt;pyshell#1&gt;", line 17, in a
    print(app.openapi())
  File "/usr/local/lib/python39/lib/site-packages/fastapi/applications.py", line 136, in openapi
    self.openapi_schema = get_openapi(
  File "/usr/local/lib/python39/lib/site-packages/fastapi/openapi/utils.py", line 410, in get_openapi
    return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True)  # type: ignore
  File "pydantic/main.py", line 406, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 2 validation errors for OpenAPI
components -&gt; schemas -&gt; FooModel -&gt; properties -&gt; prop -&gt; items
  value is not a valid dict (type=type_error.dict)
components -&gt; schemas -&gt; FooModel -&gt; $ref
  field required (type=value_error.missing)
</code></pre></div>
<p dir="auto">in fastapi.openapi.models in line 103~142</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class Schema(BaseModel):
    ref: Optional[str] = Field(None, alias=&quot;$ref&quot;)
    title: Optional[str] = None
    multipleOf: Optional[float] = None
    maximum: Optional[float] = None
    exclusiveMaximum: Optional[float] = None
    minimum: Optional[float] = None
    exclusiveMinimum: Optional[float] = None
    maxLength: Optional[int] = Field(None, gte=0)
    minLength: Optional[int] = Field(None, gte=0)
    pattern: Optional[str] = None
    maxItems: Optional[int] = Field(None, gte=0)
    minItems: Optional[int] = Field(None, gte=0)
    uniqueItems: Optional[bool] = None
    maxProperties: Optional[int] = Field(None, gte=0)
    minProperties: Optional[int] = Field(None, gte=0)
    required: Optional[List[str]] = None
    enum: Optional[List[Any]] = None
    type: Optional[str] = None
    allOf: Optional[List[&quot;Schema&quot;]] = None
    oneOf: Optional[List[&quot;Schema&quot;]] = None
    anyOf: Optional[List[&quot;Schema&quot;]] = None
    not_: Optional[&quot;Schema&quot;] = Field(None, alias=&quot;not&quot;)
    items: Optional[&quot;Schema&quot;] = None
    properties: Optional[Dict[str, &quot;Schema&quot;]] = None
    additionalProperties: Optional[Union[&quot;Schema&quot;, Reference, bool]] = None
    description: Optional[str] = None
    format: Optional[str] = None
    default: Optional[Any] = None
    nullable: Optional[bool] = None
    discriminator: Optional[Discriminator] = None
    readOnly: Optional[bool] = None
    writeOnly: Optional[bool] = None
    xml: Optional[XML] = None
    externalDocs: Optional[ExternalDocumentation] = None
    example: Optional[Any] = None
    deprecated: Optional[bool] = None

    class Config:
        extra: str = &quot;allow&quot;"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">Schema</span>(<span class="pl-v">BaseModel</span>):
    <span class="pl-s1">ref</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">str</span>] <span class="pl-c1">=</span> <span class="pl-v">Field</span>(<span class="pl-c1">None</span>, <span class="pl-s1">alias</span><span class="pl-c1">=</span><span class="pl-s">"$ref"</span>)
    <span class="pl-s1">title</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">str</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">multipleOf</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">float</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">maximum</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">float</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">exclusiveMaximum</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">float</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">minimum</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">float</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">exclusiveMinimum</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">float</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">maxLength</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">int</span>] <span class="pl-c1">=</span> <span class="pl-v">Field</span>(<span class="pl-c1">None</span>, <span class="pl-s1">gte</span><span class="pl-c1">=</span><span class="pl-c1">0</span>)
    <span class="pl-s1">minLength</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">int</span>] <span class="pl-c1">=</span> <span class="pl-v">Field</span>(<span class="pl-c1">None</span>, <span class="pl-s1">gte</span><span class="pl-c1">=</span><span class="pl-c1">0</span>)
    <span class="pl-s1">pattern</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">str</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">maxItems</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">int</span>] <span class="pl-c1">=</span> <span class="pl-v">Field</span>(<span class="pl-c1">None</span>, <span class="pl-s1">gte</span><span class="pl-c1">=</span><span class="pl-c1">0</span>)
    <span class="pl-s1">minItems</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">int</span>] <span class="pl-c1">=</span> <span class="pl-v">Field</span>(<span class="pl-c1">None</span>, <span class="pl-s1">gte</span><span class="pl-c1">=</span><span class="pl-c1">0</span>)
    <span class="pl-s1">uniqueItems</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">bool</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">maxProperties</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">int</span>] <span class="pl-c1">=</span> <span class="pl-v">Field</span>(<span class="pl-c1">None</span>, <span class="pl-s1">gte</span><span class="pl-c1">=</span><span class="pl-c1">0</span>)
    <span class="pl-s1">minProperties</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">int</span>] <span class="pl-c1">=</span> <span class="pl-v">Field</span>(<span class="pl-c1">None</span>, <span class="pl-s1">gte</span><span class="pl-c1">=</span><span class="pl-c1">0</span>)
    <span class="pl-s1">required</span>: <span class="pl-v">Optional</span>[<span class="pl-v">List</span>[<span class="pl-s1">str</span>]] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">enum</span>: <span class="pl-v">Optional</span>[<span class="pl-v">List</span>[<span class="pl-v">Any</span>]] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">type</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">str</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">allOf</span>: <span class="pl-v">Optional</span>[<span class="pl-v">List</span>[<span class="pl-s">"Schema"</span>]] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">oneOf</span>: <span class="pl-v">Optional</span>[<span class="pl-v">List</span>[<span class="pl-s">"Schema"</span>]] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">anyOf</span>: <span class="pl-v">Optional</span>[<span class="pl-v">List</span>[<span class="pl-s">"Schema"</span>]] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">not_</span>: <span class="pl-v">Optional</span>[<span class="pl-s">"Schema"</span>] <span class="pl-c1">=</span> <span class="pl-v">Field</span>(<span class="pl-c1">None</span>, <span class="pl-s1">alias</span><span class="pl-c1">=</span><span class="pl-s">"not"</span>)
    <span class="pl-s1">items</span>: <span class="pl-v">Optional</span>[<span class="pl-s">"Schema"</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">properties</span>: <span class="pl-v">Optional</span>[<span class="pl-v">Dict</span>[<span class="pl-s1">str</span>, <span class="pl-s">"Schema"</span>]] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">additionalProperties</span>: <span class="pl-v">Optional</span>[<span class="pl-v">Union</span>[<span class="pl-s">"Schema"</span>, <span class="pl-v">Reference</span>, <span class="pl-s1">bool</span>]] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">description</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">str</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">format</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">str</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">default</span>: <span class="pl-v">Optional</span>[<span class="pl-v">Any</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">nullable</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">bool</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">discriminator</span>: <span class="pl-v">Optional</span>[<span class="pl-v">Discriminator</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">readOnly</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">bool</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">writeOnly</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">bool</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">xml</span>: <span class="pl-v">Optional</span>[<span class="pl-v">XML</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">externalDocs</span>: <span class="pl-v">Optional</span>[<span class="pl-v">ExternalDocumentation</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">example</span>: <span class="pl-v">Optional</span>[<span class="pl-v">Any</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>
    <span class="pl-s1">deprecated</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">bool</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>

    <span class="pl-k">class</span> <span class="pl-v">Config</span>:
        <span class="pl-s1">extra</span>: <span class="pl-s1">str</span> <span class="pl-c1">=</span> <span class="pl-s">"allow"</span></pre></div>
<p dir="auto">It seems <code class="notranslate">Schema.items</code> should accept an array of schemas according to the JSON schema spec, but only the type <code class="notranslate">Schema</code> is allowed in the current code.</p>
<h3 dir="auto">Operating System</h3>
<p dir="auto">Linux, Windows</p>
<h3 dir="auto">Operating System Details</h3>
<p dir="auto"><em>No response</em></p>
<h3 dir="auto">FastAPI Version</h3>
<p dir="auto">0.70.0</p>
<h3 dir="auto">Python Version</h3>
<p dir="auto">Python 3.9.5</p>
<h3 dir="auto">Additional Context</h3>
<p dir="auto"><em>No response</em></p>
<h3 dir="auto">First Check</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I added a very descriptive title to this issue.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I used the GitHub search to find a similar issue and didn't find it.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I searched the FastAPI documentation, with the integrated search.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already searched in Google "How to X in FastAPI" and didn't find any information.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already read and followed all the tutorial in the docs and didn't find an answer.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/samuelcolvin/pydantic">Pydantic</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/swagger-api/swagger-ui">Swagger UI</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/Redocly/redoc">ReDoc</a>.</li>
</ul>
<h3 dir="auto">Commit to Help</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I commit to help with one of those options <g-emoji class="g-emoji" alias="point_up_2" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f446.png">👆</g-emoji></li>
</ul>
<h3 dir="auto">Example Code</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# main.py

import uvicorn
from fastapi import FastAPI, Form

app = FastAPI()

@app.post(&quot;/&quot;)
def hello(arg: tuple[int, int] = Form(...)) -&gt; str:
    pass

if __name__ == &quot;__main__&quot;:
    uvicorn.run(&quot;main:app&quot;, port=8080)"><pre class="notranslate"><span class="pl-c"># main.py</span>

<span class="pl-k">import</span> <span class="pl-s1">uvicorn</span>
<span class="pl-k">from</span> <span class="pl-s1">fastapi</span> <span class="pl-k">import</span> <span class="pl-v">FastAPI</span>, <span class="pl-v">Form</span>

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</span>()

<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">post</span>(<span class="pl-s">"/"</span>)</span>
<span class="pl-k">def</span> <span class="pl-en">hello</span>(<span class="pl-s1">arg</span>: <span class="pl-s1">tuple</span>[<span class="pl-s1">int</span>, <span class="pl-s1">int</span>] <span class="pl-c1">=</span> <span class="pl-v">Form</span>(...)) <span class="pl-c1">-&gt;</span> <span class="pl-s1">str</span>:
    <span class="pl-k">pass</span>

<span class="pl-k">if</span> <span class="pl-s1">__name__</span> <span class="pl-c1">==</span> <span class="pl-s">"__main__"</span>:
    <span class="pl-s1">uvicorn</span>.<span class="pl-en">run</span>(<span class="pl-s">"main:app"</span>, <span class="pl-s1">port</span><span class="pl-c1">=</span><span class="pl-c1">8080</span>)</pre></div>
<h3 dir="auto">Description</h3>
<ol dir="auto">
<li>Run <code class="notranslate">pip install uvicorn fastapi==0.68.0</code>.</li>
<li>Run <code class="notranslate">python ./main.py</code></li>
<li>Hit <code class="notranslate">localhost:8080/docs</code>, observe internal server error with below validation errors:</li>
</ol>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="pydantic.error_wrappers.ValidationError: 2 validation errors for OpenAPI
components -&gt; schemas -&gt; Body_hello__post -&gt; properties -&gt; arg -&gt; items
  value is not a valid dict (type=type_error.dict)
components -&gt; schemas -&gt; Body_hello__post -&gt; $ref
  field required (type=value_error.missing)"><pre class="notranslate"><code class="notranslate">pydantic.error_wrappers.ValidationError: 2 validation errors for OpenAPI
components -&gt; schemas -&gt; Body_hello__post -&gt; properties -&gt; arg -&gt; items
  value is not a valid dict (type=type_error.dict)
components -&gt; schemas -&gt; Body_hello__post -&gt; $ref
  field required (type=value_error.missing)
</code></pre></div>
<ol start="4" dir="auto">
<li>Run <code class="notranslate">pip install fastapi==0.67.0</code></li>
<li>Hit <code class="notranslate">localhost:8080/docs</code>, observe that endpoint documentation is successfully generated.</li>
</ol>
<h3 dir="auto">Operating System</h3>
<p dir="auto">Linux</p>
<h3 dir="auto">Operating System Details</h3>
<p dir="auto">Ubuntu 20.04</p>
<h3 dir="auto">FastAPI Version</h3>
<p dir="auto">0.68.0 has bug, 0.67.0 does not have bug.</p>
<h3 dir="auto">Python Version</h3>
<p dir="auto">3.9</p>
<h3 dir="auto">Additional Context</h3>
<p dir="auto">Any use of <code class="notranslate">tuple</code> in an input (<code class="notranslate">Form</code>, and <code class="notranslate">BaseModel</code> as JSON) or output (<code class="notranslate">BaseModel</code> as JSON) results in above error.</p>