pallets/flask · error · TypeError
Use the 'route' decorator to use the 'methods' argument.
Error message
Use the 'route' decorator to use the 'methods' argument.
What it means
The HTTP-method shortcut decorators (get, post, put, delete, patch) route through _method_route, which hardcodes methods=[method]. Passing methods in options would be ambiguous/contradictory, so Flask raises TypeError and points the user to the generic route() decorator instead.
Solutions
- Use @app.route('/x', methods=[...]) when you need to control methods.
- Remove the methods kwarg from the method shortcut call (the shortcut already implies the method).
- If merging options programmatically, pop 'methods' before passing to the shortcut.
Example fix
// before
@app.get('/items', methods=['GET', 'HEAD'])
def items(): ...
// after
@app.route('/items', methods=['GET', 'HEAD'])
def items(): ... Defensive patterns
Strategy: type-guard
Validate before calling
def call_method_shortcut(decorator, rule, **options):
options.pop('methods', None) # explicit guard
return decorator(rule, **options)
Type guard
def options_has_no_methods(options: dict) -> bool:
return 'methods' not in options
Prevention
- Use @app.route(methods=[...]) when methods must be customized.
- Do not forward a shared options dict into method shortcuts without popping methods.
- Document shortcuts as 'no methods kwarg' in team conventions.
When it happens
Trigger: Calling @app.get('/x', methods=['POST']); @app.post('/x', methods=['GET','POST']); passing methods= to any of get/post/put/delete/patch via kwargs.
Common situations: Copy-pasting options from an @app.route call onto a method shortcut; wanting to add HEAD/OPTIONS to a method shortcut; config-driven decorators merging options dicts that include methods.
Related errors
- Allowed methods must be a list of strings, for example…
- is an instance, not a class. Handlers can only be…
- View function mapping is overwriting an existing endpoint…
- A request was sent to
- A valid Flask application was not obtained from
AI-assisted analysis of pallets/flask@3596b1ab61 (2026-08-11).
Data as JSON: /api/errors/cb0032d0e6e1e61d.
Report an issue: GitHub.
Appendix: source
Thrown at src/flask/sansio/scaffold.py:291
"""The Jinja loader for this object's templates. By default this
is a class :class:`jinja2.loaders.FileSystemLoader` to
:attr:`template_folder` if it is set.
.. versionadded:: 0.5
"""
if self.template_folder is not None:
return FileSystemLoader(os.path.join(self.root_path, self.template_folder))
else:
return None
def _method_route(
self,
method: str,
rule: str,
options: dict[str, t.Any],
) -> t.Callable[[T_route], T_route]:
if "methods" in options:
raise TypeError("Use the 'route' decorator to use the 'methods' argument.")
return self.route(rule, methods=[method], **options)
@setupmethod
def get(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
"""Shortcut for :meth:`route` with ``methods=["GET"]``.
.. versionadded:: 2.0
"""
return self._method_route("GET", rule, options)
@setupmethod
def post(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
"""Shortcut for :meth:`route` with ``methods=["POST"]``.
.. versionadded:: 2.0
"""
return self._method_route("POST", rule, options)View on GitHub (pinned to 3596b1ab61)