<p dir="auto">when some <code class="notranslate">multipart/form-data</code> request is parsed via a<code class="notranslate"> reqparse.RequestParser()</code>, the parsing fails with</p>
<blockquote>
<p dir="auto">werkzeug.exceptions.BadRequest: 400 Bad Request: Did not attempt to load JSON data because the request Content-Type was not 'application/json'.</p>
</blockquote>
<p dir="auto">To replicate create some endpoint, which parses the request with a <code class="notranslate">reqparse.RequestParser</code> and send the requested data as <code class="notranslate">multipart/form-data</code> for example with <code class="notranslate">curl</code>.</p>
<p dir="auto">With flask version 2.0.2 (and a corresponding older werkzeug version m(i.e. &lt;2.1.1) ), this worked as expected, i.e. the request gets parsed correctly, with flask version 2.1.1 and werkzeug 2.1.1 (or newer) it fails.</p>
<p dir="auto">This happens, because with werkzeug version 2.1.1, werkzeug the behaviour of request.get_json() was changes:</p>
<p dir="auto">"Request.get_json() will raise a 400 BadRequest error if the Content-Type header is not application/json. This makes a very common source of confusion more visible. <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="231677288" data-permission-text="Title is private" data-url="https://github.com/pallets/flask/issues/2339" data-hovercard-type="issue" data-hovercard-url="/pallets/flask/issues/2339/hovercard" href="https://github.com/pallets/flask/issues/2339">#2339</a>"</p>
<p dir="auto">(c.f. <a href="https://werkzeug.palletsprojects.com/en/2.1.x/changes/" rel="nofollow">https://werkzeug.palletsprojects.com/en/2.1.x/changes/</a> or <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1138886023" data-permission-text="Title is private" data-url="https://github.com/pallets/werkzeug/issues/2339" data-hovercard-type="issue" data-hovercard-url="/pallets/werkzeug/issues/2339/hovercard" href="https://github.com/pallets/werkzeug/issues/2339">pallets/werkzeug#2339</a>)</p>
<p dir="auto"><code class="notranslate">requparse.Argument</code> now loads its location as default with</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="location=('json', 'values',)"><pre class="notranslate"><code class="notranslate">location=('json', 'values',)
</code></pre></div>
<p dir="auto">in line 77 of the <code class="notranslate">__init__</code> function and then iterates over <code class="notranslate">self.location</code> (in line 125f):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="for l in self.location:
                value = getattr(request, l, None)"><pre class="notranslate"><code class="notranslate">for l in self.location:
                value = getattr(request, l, None)
</code></pre></div>
<p dir="auto">which access <code class="notranslate">request.json</code> (first) and then  fails due to the new exception in/from werkzeug.</p>
<p dir="auto">Capturing that exception or accessing json only if the application type matches json would prevent that error and would allow to continue to use the reqparse with application types not being json.</p>
<p dir="auto">Werkzeug 2.1.0 makes <code class="notranslate">Request.get_json()</code> raise if request is not JSON, which causes reqparse to raise when it attempts to access <code class="notranslate">Request.json</code>, which it does by default for all arguments without a specified location.</p>