aio-libs/aiohttp · error · ValueError
HTTP redirects need a location to redirect to.
Error message
HTTP redirects need a location to redirect to.
What it means
HTTPMove subclasses (HTTPMovedPermanently, HTTPFound, HTTPSeeOther, HTTPTemporaryRedirect, HTTPPermanentRedirect) require a truthy location. A 3xx redirect without a Location header is invalid HTTP, so the constructor rejects falsy locations (empty string, None, empty URL).
Source
Thrown at aiohttp/web_exceptions.py:230
############################################################
# 3xx redirection
############################################################
class HTTPMove(HTTPRedirection):
def __init__(
self,
location: StrOrURL,
*,
headers: LooseHeaders | None = None,
reason: str | None = None,
text: str | None = None,
content_type: str | None = None,
) -> None:
if not location:
raise ValueError("HTTP redirects need a location to redirect to.")
super().__init__(
headers=headers, reason=reason, text=text, content_type=content_type
)
self._location = URL(location)
self.headers["Location"] = str(self.location)
@property
def location(self) -> URL:
return self._location
class HTTPMultipleChoices(HTTPMove):
status_code = 300
class HTTPMovedPermanently(HTTPMove):
status_code = 301
View on GitHub (pinned to d041d4d0fd)
Solutions
- Validate the location is non-empty before constructing the redirect.
- Provide a safe fallback URL when the source is empty.
- Build the URL with yarl.URL and confirm it is absolute before redirecting.
Example fix
# before
target = request.query.get('next', '')
raise HTTPFound(target)
# after
target = request.query.get('next') or '/'
if not target.startswith('/'):
target = '/'
raise HTTPFound(target) Defensive patterns
Strategy: validation
Validate before calling
if not location:
location = '/'
raise web.HTTPFound(location) Type guard
def has_location(loc: object) -> TypeGuard[str | URL]:
return bool(loc) Prevention
- Default redirect targets to a safe path like '/'.
- Whitelist redirect destinations to prevent open-redirect.
- Build the URL with yarl.URL and assert it is absolute.
When it happens
Trigger: HTTPFound(''), HTTPMovedPermanently(None), or building the location from a request header that is absent so it defaults to empty.
Common situations: Redirecting to a URL computed from Referer/next params that the client omitted; conditional redirect where the target ends up empty; passing a yarl.URL built from an empty string.
Related errors
- Compress wbits must between 9 and 15, zlib does not support
- 1007
- base_url must have a trailing '/'
- data and json parameters can not be used at the same time
- Cannot follow redirect with a consumed request body. Use byt
AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11).
Data as JSON: /api/errors/bcdce748af7100be.
Report an issue: GitHub.