What Causes This Error?
This error occurs when an API endpoint doesn’t return a valid Response object. All HTTP method handlers (GET, POST, etc.) in endpoint files must return a Response.
The Problem
// src/pages/api/data.ts
export async function GET() {
// ❌ No return statement
const data = await fetchData();
}
export async function GET() {
// ❌ Returning plain object
return { data: 'hello' };
}
The Fix
Return a Response Object
// src/pages/api/data.ts
export async function GET() {
const data = await fetchData();
// ✅ Return proper Response
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' },
});
}
Or Use Response.json()
export async function GET() {
const data = await fetchData();
// ✅ Shorthand for JSON response
return Response.json(data);
}
Common Scenarios
GET Endpoint
// src/pages/api/users.ts
export const prerender = false;
export async function GET() {
const users = await db.users.findMany();
return Response.json(users);
}
POST Endpoint
// src/pages/api/users.ts
export async function POST({ request }) {
const body = await request.json();
const user = await db.users.create({ data: body });
return Response.json(user, { status: 201 });
}
Error Responses
export async function GET({ params }) {
const user = await db.users.findUnique({ id: params.id });
if (!user) {
// ✅ Return error response
return new Response('User not found', { status: 404 });
}
return Response.json(user);
}
Conditional Returns
// ❌ Not all paths return
export async function GET({ params }) {
if (params.id === 'special') {
return Response.json({ special: true });
}
// Missing return for other cases!
}
// ✅ All paths return
export async function GET({ params }) {
if (params.id === 'special') {
return Response.json({ special: true });
}
return Response.json({ regular: true });
}
Early Returns
export async function POST({ request }) {
// Validate
if (!request.headers.get('authorization')) {
// ✅ Early return for errors
return new Response('Unauthorized', { status: 401 });
}
const data = await processRequest(request);
return Response.json(data);
}
Different HTTP Methods
// src/pages/api/resource.ts
export async function GET() {
return Response.json({ method: 'GET' });
}
export async function POST({ request }) {
const body = await request.json();
return Response.json({ method: 'POST', body });
}
export async function PUT({ request }) {
return Response.json({ method: 'PUT' });
}
export async function DELETE() {
return new Response(null, { status: 204 });
}
Async Operations
export async function GET() {
try {
const data = await fetchExternalAPI();
return Response.json(data);
} catch (error) {
// ✅ Return error response
return Response.json(
{ error: 'Failed to fetch' },
{ status: 500 }
);
}
}
Response Types
// JSON
return Response.json({ data: 'value' });
// Text
return new Response('Plain text');
// HTML
return new Response('<h1>Hello</h1>', {
headers: { 'Content-Type': 'text/html' },
});
// Redirect
return Response.redirect('https://example.com');
// No content
return new Response(null, { status: 204 });
// Stream
return new Response(readableStream);
TypeScript Return Type
import type { APIRoute } from 'astro';
// TypeScript will enforce Response return
export const GET: APIRoute = async ({ params }) => {
return Response.json({ id: params.id });
};
Quick Checklist
- All code paths must return a
Response - Use
Response.json()for JSON responses - Use
new Response()for other types - Include error responses in catch blocks
- Check conditional branches all return