🐛 Fix FastAPI template rendering backward compatibility bug

The transition to a newer FastAPI/Starlette version changed the signature of `Jinja2Templates.TemplateResponse` from `(name, context)` to `(request, name, context)`.

The `app/views/base.py:template_response_with_version` wrapper naively forwarded positional arguments `*args` to `original_template_response`. This caused the template name (`"files.html"`) to be passed as the `request` parameter, and the context dictionary to be passed as the `name` parameter. This resulted in Jinja2 attempting to cache the template using a dictionary as the cache key, which triggered a `TypeError: unhashable type: 'dict'`.

This commit updates the wrapper to automatically translate the legacy positional arguments `(name: str, context: dict)` into the explicit keyword arguments `request=context.get("request"), name=name, context=context` required by modern Starlette, preventing template rendering crashes across the application and restoring passing CI test suites.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
google-labs-jules[bot]
2026-03-23 14:31:06 +00:00
parent 1d9bd15a70
commit 1e69c55947
+12
View File
@@ -163,9 +163,21 @@ def _inject_global_context(ctx: dict) -> None:
def template_response_with_version(*args, **kwargs):
"""Wrapper for TemplateResponse to include version and CSRF token in all templates"""
# Handle the case where args are passed positionally as (name, context)
# which was the old FastAPI signature. The new signature requires (request, name, context)
# or keyword arguments. We translate the old positional arguments to kwargs if possible.
if len(args) == 2 and isinstance(args[0], str) and isinstance(args[1], dict):
context = args[1]
request = context.get("request")
if request is not None:
_inject_global_context(context)
return original_template_response(request=request, name=args[0], context=context, **kwargs)
# If context dict is provided, add version to it
if len(args) >= 2 and isinstance(args[1], dict):
_inject_global_context(args[1])
elif len(args) >= 3 and isinstance(args[2], dict):
_inject_global_context(args[2])
elif "context" in kwargs and isinstance(kwargs["context"], dict):
_inject_global_context(kwargs["context"])
return original_template_response(*args, **kwargs)