AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

PPR Native Form POST Returns Flight-Only Body Instead Of Full HTML Document

When a native form POST (no JavaScript) targets a partially prerendered page, the Server Action executes but the response is only inlined Flight data with no HTML shell, leaving a blank page.

highConfidence 85%Next.jsAffected V16.3.4Affected V16.3.8Affected V16.4.0Affected V16.5.0-Canary.0

Origin Analysis

The request is classified as a possible Server Action because it is a POST with multipart/form-data, but it lacks the Next-Action header. The app-render logic treats isPossibleServerAction as if it were a dynamic RSC request and passes the prerender's postponed state, causing resumeToFizzStream/continueDynamicHTMLResumeNode to emit only the suspended parts instead of a full document.
1. Clone https://github.com/jjohnson-peanelle/next-ppr-native-post-repro\n2. npm install && npm run build && npm start\n3. Disable JavaScript and open http://localhost:3000/ (PPR page)\n4. Submit the 'Save' or 'Check' form\n5. Observe the response is 200 with no doctype/html/body and the page is blank\nAlternatively run node repro.mjs from the repo.

Fixing Code Block

Edge Case Audit

This change relies on the Next-Action header being present for actual Server Action requests. If a proxy, CDN, or custom middleware strips that header, the request would be treated as a native form post and a full document will be rendered instead of a Flight response. That is not destructive but may increase response size and disable the RSC payload format. The behavior is also only tested for multipart/form-data forms; other POST content types (e.g. application/x-www-form-urlencoded) should be covered by tests. Rollback: revert the condition to (isDynamicRSCRequest || isPossibleServerAction) if unexpected regressions appear in Server Action navigations. Concurrent requests are unaffected because this only changes the serialization path, not state handling.

Ecosystem Topology