pallets/flask · error · TypeError

app.json.response() takes either args or kwargs, not both

Error message

app.json.response() takes either args or kwargs, not both

What it means

app.json.response() (the engine behind jsonify) serializes either positional arguments (treated as a value or a JSON array) or keyword arguments (treated as a JSON object) — mixing both is ambiguous because there is no sensible way to merge a list and a dict into one JSON document, so _prepare_response_obj raises TypeError.

Source

Thrown at src/flask/json/provider.py:79

        :param s: Text or UTF-8 bytes.
        :param kwargs: May be passed to the underlying JSON library.
        """
        raise NotImplementedError

    def load(self, fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any:
        """Deserialize data as JSON read from a file.

        :param fp: A file opened for reading text or UTF-8 bytes.
        :param kwargs: May be passed to the underlying JSON library.
        """
        return self.loads(fp.read(), **kwargs)

    def _prepare_response_obj(
        self, args: tuple[t.Any, ...], kwargs: dict[str, t.Any]
    ) -> t.Any:
        if args and kwargs:
            raise TypeError("app.json.response() takes either args or kwargs, not both")

        if not args and not kwargs:
            return None

        if len(args) == 1:
            return args[0]

        return args or kwargs

    def response(self, *args: t.Any, **kwargs: t.Any) -> Response:
        """Serialize the given arguments as JSON, and return a
        :class:`~flask.Response` object with the ``application/json``
        mimetype.

        The :func:`~flask.json.jsonify` function calls this method for
        the current application.

        Either positional or keyword arguments can be given, not both.

View on GitHub ↗ (pinned to 6a2f545bfd)

Solutions

  1. Merge everything into one dict and pass it positionally: jsonify({**user_dict, 'extra': 1}).
  2. Or pass only keyword arguments: jsonify(name=name, extra=1).
  3. To set status/headers, return a tuple: return jsonify(data), 201, {'X-Header': 'v'}.

Example fix

# before
return jsonify(user, status='ok')
# after
return jsonify({**user, 'status': 'ok'})
Defensive patterns

Strategy: validation

Validate before calling

def make_json_response(app, *args, **kwargs):
    if args and kwargs:
        raise TypeError('pass either positional data or keyword fields to app.json.response, not both')
    return app.json.response(*args, **kwargs)

Try / catch

try:
    return app.json.response(data)
except TypeError:
    # mixed args/kwargs — normalize to a single dict first
    return app.json.response({**base, **extra})

Prevention

When it happens

Trigger: jsonify(data, status='ok') or app.json.response({'a': 1}, b=2) — any call combining at least one positional arg with at least one keyword arg.

Common situations: Trying to add extra fields to an existing dict via kwargs (jsonify(user_dict, extra=1)); passing a status or headers kwarg to jsonify thinking it works like Response; refactors that leave a stray positional arg.

Related errors


AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31). Data as JSON: /data/errors/21d9f3e63c5ba104.json. Report an issue: GitHub ↗.