withastro/astro · error · AstroError

RewriteWithBodyUsed

RewriteWithBodyUsed

Error message

`Astro.rewrite()` cannot be used if the request body has already been read. If you need to read the body, first clone the request.

What it means

RewriteWithBodyUsed: copyRequest() refused to build the rewrite request because oldRequest.bodyUsed is true. Astro.rewrite() needs to forward the original body to the new route; once the body has been consumed (e.g. await request.json()), it can no longer be transferred, so the rewrite is blocked.

Source

Thrown at packages/astro/src/core/routing/rewrite.ts:153

/**
 * Utility function that creates a new `Request` with a new URL from an old `Request`.
 *
 * @param newUrl The new `URL`
 * @param oldRequest The old `Request`
 * @param isPrerendered It needs to be the flag of the previous routeData, before the rewrite
 * @param logger
 * @param routePattern
 */
export function copyRequest(
	newUrl: URL,
	oldRequest: Request,
	isPrerendered: boolean,
	logger: AstroLogger,
	routePattern: string,
): Request {
	if (oldRequest.bodyUsed) {
		throw new AstroError(AstroErrorData.RewriteWithBodyUsed);
	}
	return createRequest({
		url: newUrl,
		method: oldRequest.method,
		body: oldRequest.body,
		isPrerendered,
		logger,
		headers: isPrerendered ? {} : oldRequest.headers,
		routePattern,
		init: {
			referrer: oldRequest.referrer,
			referrerPolicy: oldRequest.referrerPolicy,
			mode: oldRequest.mode,
			credentials: oldRequest.credentials,
			cache: oldRequest.cache,
			redirect: oldRequest.redirect,
			integrity: oldRequest.integrity,
			signal: oldRequest.signal,

View on GitHub (pinned to d081033d5f)

Solutions

  1. Read from a clone: const data = await Astro.request.clone().formData(); then Astro.rewrite().
  2. Reorder logic so Astro.rewrite() happens before any body read.
  3. If the body is unneeded, rewrite without reading it at all.

Example fix

// before
const data = await Astro.request.formData();
Astro.rewrite('/other'); // bodyUsed === true → throws

// after
const data = await Astro.request.clone().formData();
Astro.rewrite('/other');
Defensive patterns

Strategy: validation

Validate before calling

function bodyIsReadable(request: Request): boolean {
  return !request.bodyUsed;
}
// before Astro.rewrite, ensure body hasn't been consumed

Type guard

function requestBodyAvailable(request: Request): boolean {
  return !request.bodyUsed;
}

Prevention

When it happens

Trigger: Awaiting Astro.request.json()/.formData()/.text() and then calling Astro.rewrite(); middleware reading the body before a downstream Astro.rewrite(); an action consuming input then rewriting.

Common situations: Reading POST data to decide whether to rewrite, then rewriting; middleware parsing the body; form handlers that inspect input before routing.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/71dfe809a60297be. Report an issue: GitHub.