{"record":{"id":"d7d0b9069440b499","repo":"pallets/flask","slug":"view-function-mapping-is-overwriting-an-existing-e","errorCode":null,"errorMessage":"View function mapping is overwriting an existing endpoint function: {endpoint}","messagePattern":"View function mapping is overwriting an existing endpoint function: (.+?)","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"src/flask/sansio/app.py","lineNumber":657,"sourceCode":"                provide_automatic_options = (\n                    \"OPTIONS\" not in methods\n                    and self.config[\"PROVIDE_AUTOMATIC_OPTIONS\"]\n                )\n\n        if provide_automatic_options:\n            required_methods.add(\"OPTIONS\")\n\n        # Add the required methods now.\n        methods |= required_methods\n\n        rule_obj = self.url_rule_class(rule, methods=methods, **options)\n        rule_obj.provide_automatic_options = provide_automatic_options  # type: ignore[attr-defined]\n\n        self.url_map.add(rule_obj)\n        if view_func is not None:\n            old_func = self.view_functions.get(endpoint)\n            if old_func is not None and old_func != view_func:\n                raise AssertionError(\n                    \"View function mapping is overwriting an existing\"\n                    f\" endpoint function: {endpoint}\"\n                )\n            self.view_functions[endpoint] = view_func\n\n    @t.overload\n    def template_filter(self, name: T_template_filter) -> T_template_filter: ...\n    @t.overload\n    def template_filter(\n        self, name: str | None = None\n    ) -> t.Callable[[T_template_filter], T_template_filter]: ...\n    @setupmethod\n    def template_filter(\n        self, name: T_template_filter | str | None = None\n    ) -> T_template_filter | t.Callable[[T_template_filter], T_template_filter]:\n        \"\"\"Decorate a function to register it as a custom Jinja filter. The name\n        is optional. The decorator may be used without parentheses.\n","sourceCodeStart":639,"sourceCodeEnd":675,"githubUrl":"https://github.com/pallets/flask/blob/3596b1ab61cea85edb8970e83ff61daa073facf8/src/flask/sansio/app.py#L639-L675","documentation":"Flask stores view functions in a dict keyed by endpoint name (app.view_functions). add_url_rule checks if an endpoint already maps to a DIFFERENT callable; if so it raises AssertionError to prevent a silent override. Registering the same function again (e.g. re-import) is allowed.","triggerScenarios":"Two different view functions resolving to the same endpoint (default endpoint = view_func.__name__); explicitly passing endpoint='x' to two distinct functions; a blueprint and an app route colliding on endpoint name; functools.partial or lambda views colliding on default name.","commonSituations":"Naming two views the same (e.g. two index functions in different modules), Flask's default endpoint-from-view-func colliding, blueprint registration without name_prefix producing colliding dotted endpoints, double-decorating the same function path.","solutions":["Give each conflicting view a distinct endpoint via endpoint='unique_name', or rename one of the functions.","Register blueprints with unique names (name= or name_prefix=) so blueprint endpoints do not collide with app-level endpoints.","Check for duplicate route registration caused by importing the same module twice; deduplicate the imports.","Inspect app.view_functions keys at startup to find the duplicate before it raises."],"exampleFix":"// before\n@app.route('/a')\ndef index(): ...\n@app.route('/b')  # default endpoint 'index' collides\ndef index(): ...\n\n// after\n@app.route('/a')\ndef index(): ...\n@app.route('/b', endpoint='index_b')\ndef index_b(): ...","handlingStrategy":"validation","validationCode":"def assert_endpoint_free(app, endpoint):\n    if endpoint in app.view_functions:\n        raise ValueError(f'endpoint {endpoint!r} already registered to {app.view_functions[endpoint]!r}')\n","typeGuard":"def endpoint_is_unique(app, endpoint: str) -> bool:\n    return endpoint not in app.view_functions\n","tryCatchPattern":"try:\n    app.add_url_rule('/x', endpoint='x', view_func=fn)\nexcept AssertionError as e:\n    if 'overwriting an existing endpoint' in str(e):\n        # choose a different endpoint name and retry\n        raise","preventionTips":["Always pass explicit endpoint= for route factories or dynamic routes.","Dump app.view_functions keys at startup to catch collisions early.","Keep blueprint and app endpoint namespaces disjoint with unique prefixes."],"tags":["flask","routing","endpoint","assertion","duplicate"],"backgroundTag":null,"analyzedSha":"3596b1ab61cea85edb8970e83ff61daa073facf8","analyzedAt":"2026-08-11T20:11:52.622Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}