solid-start icon indicating copy to clipboard operation
solid-start copied to clipboard

[Bug?]: Set-Cookie header not applied to request during single-flight mutation (SFM)

Open yinonburgansky opened this issue 5 months ago • 1 comments

Duplicates

  • [x] I have searched the existing issues

Latest version

  • [x] I have tested the latest version

Current behavior 😯

When a server action throws a redirect with a Set-Cookie header, the cookie is applied to the response but not merged into the subsequent server-side request context of the single flight mutation.
That means any server queries that read cookies from the incoming request during the same flight won't see the newly-set cookie. The behavior differs from a full client round-trip, where the browser would include the cookie on the next request.

Expected behavior 🤔

Single-flight mutations should behave as if a round trip occurred: any headers (such as Set-Cookie, referrer) set on the response should be reflected in the request for subsequent server logic, to ensure consistent behavior.

Steps to reproduce 🕹

const serverFunc = action(async () => {
	"use server"
	throw redirect("/", {
		headers: {
			"Set-Cookie": "val=1234; Path=/; HttpOnly; SameSite=Lax; Max-Age=3600",
		}
	})
}, "serverFunc")

yinonburgansky avatar Sep 04 '25 12:09 yinonburgansky

If you want a quick fix, use setCookie() before throwing instead of adding header to redirect(). I know that will work for sure now https://github.com/solidjs/solid-start/issues/1703

setCookie("val", "1234", {
  path: "/",
  httpOnly: true,
  sameSite: "lax",
  maxAge: 3600,
})
throw redirect("/")

If you want the redirect headers to get merged, here's the code that needs to change for single flight requests.

https://github.com/solidjs/solid-start/blob/375155d81c54b03351b1c985a6984d68d61c4b8f/packages/start/src/server/server-functions-handler.ts#L308-L327

RIght now, the headers are created from only the sourceEvent.

After throwing a redirect, result will be a 302 response with the headers you pass it along with Location and X-Revalidate. So basically, merge the sourceEvent headers with the result headers, minus unwanted headers like Location and X-Revalidate

zhengkyl avatar Dec 08 '25 23:12 zhengkyl