withastro/astro · error · AstroError
OnlyResponseCanBeReturned
OnlyResponseCanBeReturned
Error message
Route `${route}` returned a `${returnedValue}`. Only a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) can be returned from Astro files. What it means
When a page's component factory result is a head+content wrapper (`isHeadAndContent`), Astro expects the wrapper's `.content` to itself be a valid render-template result. If it isn't, the page returned something that is neither a `Response` nor a renderable template, so Astro throws `OnlyResponseCanBeReturned` with the route and the value's type. Pages must return a `Response` (or render normally without returning).
Source
Thrown at packages/astro/src/runtime/server/render/astro/render.ts:323
}
async function callComponentAsTemplateResultOrResponse(
result: SSRResult,
componentFactory: AstroComponentFactory,
props: any,
children: any,
route?: RouteData,
) {
const factoryResult = await componentFactory(result, props, children);
if (factoryResult instanceof Response) {
return factoryResult;
}
// we check if the component we attempt to render is a head+content
else if (isHeadAndContent(factoryResult)) {
// we make sure that content is valid template result
if (!isRenderTemplateResult(factoryResult.content)) {
throw new AstroError({
...AstroErrorData.OnlyResponseCanBeReturned,
message: AstroErrorData.OnlyResponseCanBeReturned.message(
route?.route,
typeof factoryResult,
),
location: {
file: route?.component,
},
});
}
// return the content
return factoryResult.content;
} else if (!isRenderTemplateResult(factoryResult)) {
throw new AstroError({
...AstroErrorData.OnlyResponseCanBeReturned,
message: AstroErrorData.OnlyResponseCanBeReturned.message(route?.route, typeof factoryResult),
location: {View on GitHub (pinned to d081033d5f)
Solutions
- Do not return arbitrary values from an Astro page; render markup normally or return a `Response`.
- To send a redirect or custom status, `return new Response(null, { status, headers })` or `return Astro.redirect(...)`.
- If you construct head+content structures manually (integration/plugin), ensure `.content` is a render-template result.
Example fix
// before — page returns a plain object
---
return { html: '<p>hi</p>' };
---
// after — return a Response
---
return new Response('<p>hi</p>', { headers: { 'content-type': 'text/html' } });
--- Defensive patterns
Strategy: validation
Validate before calling
// Ensure page frontmatter only returns a Response (or nothing)
function assertPageReturn(value: unknown): Response | void {
if (value instanceof Response) return value;
if (value === undefined) return;
throw new Error('Astro pages may only return a Response');
} Type guard
const isPageResponse = (v: unknown): v is Response => v instanceof Response;
Prevention
- Never `return` raw data from an `.astro` page; render it instead.
- Use API endpoints (handler exports) for data-only responses.
- If returning from a page, return only a `Response`.
When it happens
Trigger: A `.astro` page `return`s an object/value that wraps content incorrectly; a manually constructed head+content-like structure with a malformed `.content`; returning a non-Response, non-template value from page frontmatter.
Common situations: Returning a custom object or string from `.astro` frontmatter expecting it to be the response body; interfering with Astro's internal content wrappers via an integration.
Related errors
- ResponseSentError
- ActionsReturnedInvalidDataError
- CompilerError
- ResponseSentError
- MiddlewareNotAResponse
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/ab2c2d27036d56d8.
Report an issue: GitHub.