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

JSONProvider._prepare_response_obj(args, kwargs) is used by response()/jsonify. If BOTH positional args and keyword args are supplied (args and kwargs both truthy), it raises TypeError. The API contract is: give either a single positional value, multiple positional values (serialized as a list), or keyword args (serialized as a dict)—never both.

Solutions

  1. Pass data either positionally or as keywords, not both: jsonify(myobj) or jsonify(key=value).
  2. If you need a dict plus extra keys, merge them first: jsonify({**myobj, 'extra': 'x'}).
  3. For multiple values use only positional args (they become a list) or only keyword args (they become a dict).

Example fix

# before
return jsonify(data, status='ok')  # both args and kwargs -> TypeError

# after
return jsonify({**data, 'status': 'ok'})  # kwargs only
Defensive patterns

Strategy: validation

Validate before calling

def validate_response_args(args: tuple, kwargs: dict):
    if args and kwargs:
        raise TypeError('Pass either positional args OR kwargs, not both')
    return True

Type guard

def uses_single_channel(args: tuple, kwargs: dict) -> bool:
    return not (args and kwargs)

Try / catch

try:
    app.json.response(obj, key='x')
except TypeError as e:
    if 'either args or kwargs' in str(e):
        resp = app.json.response({**obj, 'key': 'x'})
    else:
        raise

Prevention

When it happens

Trigger: Calling app.json.response(obj, key=val) or jsonify(value, extra='x'). Passing any mix where at least one positional and one keyword argument are present. _prepare_response_obj checks args and kwargs and rejects the combination before serialization.

Common situations: Refactoring a jsonify call and accidentally combining a positional data argument with a keyword. Calling response() directly with mixed arguments. Migrating from an older custom JSON helper that accepted both.

Related errors


AI-assisted analysis of pallets/flask@3596b1ab61 (2026-08-11). Data as JSON: /api/errors/21d9f3e63c5ba104. Report an issue: GitHub.

Appendix: 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 3596b1ab61)