withastro/astro · error · AstroError
RedirectWithNoLocation
RedirectWithNoLocation
Error message
A redirect must be given a location with the `Location` header.
What it means
Thrown by getRedirectLocationOrThrow() when a Response with a 3xx redirect status lacks a 'location' header. Astro requires every redirect Response to carry a Location header so the browser knows where to navigate. Without it the redirect is meaningless and the runtime refuses to serve it.
Source
Thrown at packages/astro/src/core/redirects/validate.ts:7
import { AstroError, AstroErrorData } from '../errors/index.js';
export function getRedirectLocationOrThrow(headers: Headers): string {
let location = headers.get('location');
if (!location) {
throw new AstroError({
...AstroErrorData.RedirectWithNoLocation,
});
}
return location;
}
View on GitHub (pinned to d081033d5f)
Solutions
- Use Astro.redirect('/path') which sets the Location header automatically.
- If building the Response manually, always pass headers: { Location: '/target' }.
- Inspect middleware/onRequest handlers that touch Astro.response or the returned Response to ensure they preserve Location.
- Log response.headers.get('location') right before returning to confirm the header is present.
Example fix
// before
return new Response(null, { status: 302 });
// after
return new Response(null, { status: 302, headers: { Location: '/login' } });
// or simply
return Astro.redirect('/login'); Defensive patterns
Strategy: validation
Validate before calling
function hasRedirectLocation(response: Response): boolean {
return Boolean(response.headers.get('location'));
}
// before returning a redirect:
const res = new Response(null, { status: 302, headers: { Location: '/x' } });
if (!hasRedirectLocation(res)) throw new Error('missing Location'); Type guard
function isRedirectWithLocation(res: Response): res is Response & { headers: Headers } {
return res.status >= 300 && res.status < 400 && res.headers.has('location');
} Try / catch
try {
const loc = getRedirectLocationOrThrow(response.headers);
} catch (e) {
// ensure Location is set before retrying
response.headers.set('Location', '/fallback');
} Prevention
- Prefer Astro.redirect(url) which always sets Location.
- In tests, assert response.headers.has('location') for every redirect.
- Audit middleware that touches the returned Response to preserve Location.
When it happens
Trigger: Returning a Response with status 301/302/307/308 but no 'Location' header; calling Astro.redirect() and then mutating the Response to strip the header; manually constructing new Response(null, { status: 302 }) without headers; an integration or middleware replacing response headers.
Common situations: Manually building a redirect Response in an endpoint or page instead of using Astro.redirect(url); middleware that clones a redirect Response and drops headers; adapter/proxy that strips Location before Astro reads it.
Related errors
- ResponseSentError
- MiddlewareNotAResponse
- MiddlewareNoDataOrNextCalled
- ResponseSentError
- ActionCalledFromServerError
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/45a03e27a9ee5589.
Report an issue: GitHub.