pallets/flask · error · AssertionError
View function mapping is overwriting an existing endpoint fu
Error message
View function mapping is overwriting an existing endpoint function: {endpoint} What it means
An AssertionError from `Flask.add_url_rule` (src/flask/sansio/app.py:654-660). Flask maps each endpoint name to exactly one view function in `self.view_functions`; if the endpoint already has a function and the new `view_func` is a *different* object, registration would silently replace the old view, so Flask refuses. Registering the identical function object again for the same endpoint is allowed (the `old_func != view_func` check), which is why re-importing the same module is fine but a name collision is not.
Source
Thrown at src/flask/sansio/app.py:657
provide_automatic_options = (
"OPTIONS" not in methods
and self.config["PROVIDE_AUTOMATIC_OPTIONS"]
)
if provide_automatic_options:
required_methods.add("OPTIONS")
# Add the required methods now.
methods |= required_methods
rule_obj = self.url_rule_class(rule, methods=methods, **options)
rule_obj.provide_automatic_options = provide_automatic_options # type: ignore[attr-defined]
self.url_map.add(rule_obj)
if view_func is not None:
old_func = self.view_functions.get(endpoint)
if old_func is not None and old_func != view_func:
raise AssertionError(
"View function mapping is overwriting an existing"
f" endpoint function: {endpoint}"
)
self.view_functions[endpoint] = view_func
@t.overload
def template_filter(self, name: T_template_filter) -> T_template_filter: ...
@t.overload
def template_filter(
self, name: str | None = None
) -> t.Callable[[T_template_filter], T_template_filter]: ...
@setupmethod
def template_filter(
self, name: T_template_filter | str | None = None
) -> T_template_filter | t.Callable[[T_template_filter], T_template_filter]:
"""Decorate a function to register it as a custom Jinja filter. The name
is optional. The decorator may be used without parentheses.
View on GitHub ↗ (pinned to 6a2f545bfd)
Solutions
- Add `@functools.wraps(f)` to any custom decorator applied between `@app.route` and the view function — this is the most common cause.
- Rename the colliding view function or pass a unique `endpoint='...'` to one of the routes.
- If the same handler should serve two URLs, stack multiple `@app.route` decorators on one function instead of defining two functions.
- Check for double registration (module imported under two names, or setup code running twice) and register routes exactly once.
Example fix
# before
def login_required(f):
def wrapper(*a, **kw):
return f(*a, **kw)
return wrapper # every view becomes endpoint 'wrapper'
# after
import functools
def login_required(f):
@functools.wraps(f)
def wrapper(*a, **kw):
return f(*a, **kw)
return wrapper Defensive patterns
Strategy: validation
Validate before calling
if 'my_endpoint' in app.view_functions:
raise RuntimeError('endpoint already registered')
app.add_url_rule('/x', 'my_endpoint', view) Type guard
def endpoint_free(app, endpoint):
return endpoint not in app.view_functions Try / catch
try:
app.add_url_rule(rule, endpoint, view)
except AssertionError:
log.error('Endpoint %s collides; pick a unique endpoint name', endpoint) Prevention
- Give every view function a unique name, or pass an explicit unique endpoint= argument
- Beware decorators that don't use functools.wraps — wrapped views all become named 'wrapper'
- When registering routes in loops, derive the endpoint from the loop variable, not the function name
When it happens
Trigger: Two `@app.route` decorators on functions with the same name (endpoint defaults to `view_func.__name__`); explicitly passing the same `endpoint=` to two different views; decorating a view with a custom decorator that doesn't use `functools.wraps`, so every wrapped view is named 'wrapper' and the second registration collides; registering the same blueprint module's routes twice under one name; calling `add_url_rule` twice with different functions for one endpoint.
Common situations: Copy-pasting a route and forgetting to rename the function; custom auth/logging decorators missing `@functools.wraps(f)`; app modules imported twice via different paths (package vs script) creating distinct function objects; hot-reload or plugin code re-registering routes on a long-lived app.
Related errors
- 'endpoint' may not contain a dot '.' character.
- 'copy_current_request_context' can only be used when a reque
- The setup method '{f_name}' can no longer be called on the a
- Allowed methods must be a list of strings, for example: @app
- Working outside of application context. Attempted to use fu
AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31).
Data as JSON: /data/errors/d7d0b9069440b499.json.
Report an issue: GitHub ↗.