AssertionError: View function mapping is overwriting an existing endpoint function

avatar
Borislav Hadzhiev

Last updated: Apr 11, 2024
4 min

banner

# AssertionError: View function mapping is overwriting an existing endpoint function

The Flask error "AssertionError: View function mapping is overwriting an existing endpoint function" occurs for 2 main reasons:

  1. Having multiple view functions with the same name in the same Flask application.
  2. Wrapping multiple route handler functions with the same decorators without supplying different names for each function.

view function mapping is overwriting an existing endpoint function

Here is a simple example of how the error occurs.

app.py
from flask import Flask app = Flask(__name__) @app.route("/") def main(): return "<p>Home: bobbyhadz.com</p>" @app.route("/about") def main(): return "<p>About: bobbyhadz.com</p>" # ⛔️ AssertionError: View function mapping is overwriting an existing endpoint function: main if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)

If I run my Flask application with python app.py, the AssertionError is raised.

The cause of the error is that we have 2 view functions with the same name (main in the example).

Even though the routes are different (/ and /about), the two view functions cannot have the same name.

You can resolve the issue by renaming the second view function so they no longer clash.

app.py
from flask import Flask app = Flask(__name__) @app.route("/") def main(): return "<p>Home: bobbyhadz.com</p>" @app.route("/about") def about(): return "<p>About: bobbyhadz.com</p>" if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)

Now the first view function is named main and the second about, so they no longer clash.

view functions no longer clash

# Solving the error when using multiple decorators for multiple view functions

You might also get the error when using multiple decorators for multiple view functions.

Here is an example.

app.py
from flask import Flask app = Flask(__name__) def exception_handler(func): def wrapper(*args, **kwargs): print('exception handled') return wrapper @app.route('/') @exception_handler def main(): return "<p>Home: bobbyhadz.com</p>" @app.route('/about') @exception_handler def about(): return "<p>About: bobbyhadz.com</p>" # ⛔️ AssertionError: View function mapping is overwriting an existing endpoint function: wrapper if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)

Running my application with python app.py produces the same AssertionError.

error caused by multiple decorators

We wrapped the two view functions with the same 2 decorators which caused the error.

You can resolve the issue by passing the endpoint keyword argument in the call to @app.route().

app.py
from flask import Flask app = Flask(__name__) def exception_handler(func): def wrapper(*args, **kwargs): print('exception handled') return wrapper # 1) Set the endpoint keyword argument @app.route('/', endpoint='home') @exception_handler def main(): return "<p>Home: bobbyhadz.com</p>" # 2) Set the endpoint keyword argument @app.route('/about', endpoint='about') @exception_handler def about(): return "<p>About: bobbyhadz.com</p>" if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)

If I start my Flask application with python app.py, everything works as expected.

shell
python app.py

everything works as expected

Note that the value of the endpoint argument has to be different for the different routes.

app.py
# 1) Set the endpoint keyword argument @app.route('/', endpoint='home') @exception_handler def main(): return "<p>Home: bobbyhadz.com</p>" # 2) Set the endpoint keyword argument @app.route('/about', endpoint='about') @exception_handler def about(): return "<p>About: bobbyhadz.com</p>"

If you specify the same endpoint for multiple routes, the error is raised.

You can also solve the error by setting the name of the wrapper function in the decorator to a unique value.

app.py
from flask import Flask app = Flask(__name__) def exception_handler(func): def wrapper(*args, **kwargs): print('exception handled') # ✅ Set the name of the wrapper function to a unique value wrapper.__name__ = func.__name__ return wrapper @app.route('/') @exception_handler def main(): return "<p>Home: bobbyhadz.com</p>" @app.route('/about') @exception_handler def about(): return "<p>About: bobbyhadz.com</p>" if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)

I made a change to the exception_handler decorator function.

main.py
def exception_handler(func): def wrapper(*args, **kwargs): print('exception handled') # ✅ Set the name of the wrapper function to a unique value wrapper.__name__ = func.__name__ return wrapper

The decorator takes the view function as a parameter and sets the name of the wrapper function to the name of the view function.

This approach also solves the error, assuming your view functions have different names.

If your view functions have the same name (e.g. main), using this approach won't solve the error because we're simply setting the name of the wrapper function to the name of each view function.

You can also use the functools.wraps decorator to solve the error.

app.py
from functools import wraps from flask import Flask app = Flask(__name__) def exception_handler(func): # ✅ Using functools.wraps @wraps(func) def wrapper(*args, **kwargs): print('exception handled') return wrapper @app.route('/') @exception_handler def main(): return "<p>Home: bobbyhadz.com</p>" @app.route('/about') @exception_handler def about(): return "<p>About: bobbyhadz.com</p>" if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)

Make sure to import wraps from functools as shown in the code sample.

I used the wraps() method in the decorator function.

app.py
from functools import wraps def exception_handler(func): # ✅ Using functools.wraps @wraps(func) def wrapper(*args, **kwargs): print('exception handled') return wrapper

The functools.wraps decorator is used when defining a wrapper function.

Without the use of the @wraps() decorator, the name of the function would have been wrapper.

Using the @wraps() decorator enables us to preserve the name and the docstring of the decorated function.

# Solving the error when using app.add_url_rule()

You might also get the error if you pass multiple view functions with the same name to the app.add_url_rule() method.

app.py
from flask import Flask app = Flask(__name__) # 1) View function named `main` def main(): return "<p>Home: bobbyhadz.com</p>" # 👇️ Passing view_func= main app.add_url_rule('/', view_func=main, methods=['GET']) # 2) View function named `main` again def main(): return "<p>About: bobbyhadz.com</p>" # 👇️ Passing view_func= main again app.add_url_rule('/about', view_func=main, methods=['GET']) # ⛔️ AssertionError: View function mapping is overwriting an existing endpoint function: main if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)

Running the code sample with python app.py produces the same error.

calling add url rule with view functions-same-name

Notice that we passed a view function with the name of main twice to the app.add_url_rule() method.

To solve the error, rename the second view function so that the names don't clash.

main.py
from flask import Flask app = Flask(__name__) def main(): return "<p>Home: bobbyhadz.com</p>" # 1) View function named `main` app.add_url_rule('/', view_func=main, methods=['GET']) def about(): return "<p>About: bobbyhadz.com</p>" # 1) View function named `about` app.add_url_rule('/about', view_func=about, methods=['GET']) if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)

After renaming the second view function everything works as expected.

renamed second view function

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.