Diagnostics

LUM5004: Head or status change inside a streamed boundary

The status, headers, cookies or head changed after the SSR shell was sent.

Severity: error · Category: routing and server (5xxx)

Reported by: the server runtime.

#What it means

A server response starts with the shell: everything outside <Suspense>. Once it is sent, the status line, headers (including Set-Cookie) and <head> are on the wire. Content inside a streamed <Suspense> boundary that calls response().setStatus(), setHeader(), cookies().set(), redirect(), or renders <Title>/<Meta>/<Head> is too late.

#Example

tsx
export default function Product() {
  return (
    <Suspense fallback={<p>Loading…</p>}>
      <Details />
    </Suspense>
  );
}

async function Details() {
  const product = await fetchJSON<Product>("/api/product");
  return <Title>{product.name}</Title>;
}

#How to fix it

Decide status, headers, cookies and head content in the shell: in middleware, in headers(ctx), or in components outside <Suspense> (an async component without a boundary holds the shell until it resolves). Keep <Suspense> for content that can stream.