If you are building a modern web application using TanStack Start and Better Auth, you might have hit a specific, frustrating wall.
You have your authentication set up, the client-side an active organization or updating a profile, the request fails or acts as if the user isn't logged in.
I recently spent hours debugging this exact issue while trying to implement an organization switcher. The solution is simple, but not immediately obvious if you are new to TanStack's server utilities: You need to manually forward the request headers.
The Problem: Missing Context
When you use Better Auth (or many other auth libraries), the server needs to know who is making the request. Usually, this information (session tokens or cookies) lives in the HTTP headeres.
In a standard client-side fetch, the browser handless cookies automatically. However, when you use a TanStack Start Server Function (createServerFn), you are running logic in an isolated server environment. If you make a call to your auth API from there without passing the original request's context, Better Auth sees an anonymous request.
The Solution: getRequest
To fix this, TanStack Start provides a utility called getRequest from @tanstack/react-start/server.
This allows you to access the incoming request object, extract the headers, and pass them along to Better Auth.
Here is the practical example that solved it for me. I wanted to create a server function to switch the user's active organization:
The code
import { getRequest } from "@tanstack/react-start/server";
import { createServerFn } from "@tanstack/start";
import { z } from "zod";
import { auth } from "./auth"; // Your Better Auth instance
export const switchOrganization = createServerFn().inputValidator(z.object({
organizationId: z.string().min(1),
})).handler(async ({data}) => {
// 1. Get the current request context
const request = getRequest();
// 2. Pass the headers to Better Auth
const organization = await auth.api.setActiveOrganization({
body: {
organizationId: data.organizationId
},
// This is the magic line that makes auth work:
headers: request.headers,
})
return organization;
})
Why This Works
-
getRequest(): This function retrives the standard Request object for the current server execution. -
headers: request.headers: By passing these headers into theauth.api.setActiveOrganizationconfiguration, you are forwading the user's session cookies. Better Auth can now read those cookies, validate the session, and confirm that the user actually has permission to switch organizations.
Summary
When working with Server Functions (RPCs) in TanStack Start, never assume the context is passed automatically to third-party libraries.If you are getting "Unauthorized" erros or weird behaviors on server-side mutations, check if you are forwading the headers. It's a small addition to your code, but it's the bridge that makes TanStack Start and Better Auth work seamlessly together.
for more information you can visit my website
Top comments (0)