better-auth breaking changes
Every breaking API change we have recorded in better-auth on npm: 328 breaking changes in 19 versions. Below are its newest 6 versions, removals and renames first, each with its source.
Newest change September 30, 2026

On this page
1.7.7
- Behavior changed
Servers sharing verification storage must be upgraded together, and users must request new Magic Links. Pending OAuth and SAML sign-ins must be restarted. github.com - Behavior changed
disableSignUp
Social ID-token sign-in now honors disableSignUp, so it can block account creation that previously happened. github.com - Behavior changed
oAuthProxy
Mixed versions cannot exchange proxy state or profiles, and the state cookie encryption key changed with no fallback. Restart sign-in and account-linking flows started before the cutover. better-auth.com
1.7.6
- Behavior changed
maxPasswordLength
Passwords over the maxPasswordLength limit now fail with PASSWORD_TOO_LONG before hashing or verification. Code that relied on longer passwords being accepted must shorten them or raise the configured limit. github.com - Signature changed
client/plugins:AdminOptions.bannedUserMessage
Was bannedUserMessage?: string | undefined; now bannedUserMessage?: string | ((user: UserWithRole & Record<string, unknown>) => Awaitable<string>) | undefined. npmjs.com - Signature changed
oauth2:handleOAuthUserInfo
Was function handleOAuthUserInfo(c: GenericEndpointContext, opts: {userInfo: Omit<User, "createdAt" | "updatedAt">; account: Omit<Account, "id" | "userId" | "createdAt" | "updatedAt">; callbackURL?: string | undefined; disableSignUp?... npmjs.com - Signature changed
plugins:CaptchaOptions
Was type CaptchaOptions = GoogleRecaptchaOptions | CloudflareTurnstileOptions | HCaptchaOptions | CaptchaFoxOptions; now type CaptchaOptions = GoogleRecaptchaOptions | CloudflareTurnstileOptions | HCaptchaOptions | CaptchaFoxOptions |... npmjs.com
1.7.5
- Signature changed
api:getEndpoints
Was function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<AuthContext>, options: Option): {api: OverrideMerge<{readonly ok: _$better_call0.StrictEndpoint<"/ok", {method: "GET"; metadata: {openapi: {description: string... npmjs.com - Signature changed
api:linkSocialAccount
Was const linkSocialAccount: _$better_call0.StrictEndpoint<"/link-social", {method: "POST"; requireHeaders: true; body: z.ZodObject<{callbackURL: z.ZodOptional<z.ZodString>; provider: z.ZodType<(string & {}) | "linear" | "huggingface" |... npmjs.com - Signature changed
api:router
Was const router: <Option extends BetterAuthOptions>(ctx: AuthContext, options: Option) => {handler: (request: Request) => Promise<Response>; endpoints: UnionToIntersection<Option["plugins"] extends (infer T)[] ? T extends BetterAuthPlugin... npmjs.com - Signature changed
api:signInSocial
Was const signInSocial: <O extends BetterAuthOptions>() => _$better_call0.StrictEndpoint<"/sign-in/social", {method: "POST"; operationId: string; body: z.ZodObject<{callbackURL: z.ZodOptional<z.ZodString>; newUserCallbackURL... npmjs.com - Signature changed
client:invitationSchema
Was const invitationSchema: z.ZodObject<{id: z.ZodDefault<z.ZodString>; organizationId: z.ZodString; email: z.ZodString; role: z.ZodString; status: z.ZodDefault<z.ZodEnum<{canceled: "canceled"; pending: "pending"; accepted: "accepted"... npmjs.com - Signature changed
client:invitationStatus
Was const invitationStatus: z.ZodDefault<z.ZodEnum<{canceled: "canceled"; pending: "pending"; accepted: "accepted"; rejected: "rejected";}>>; now const invitationStatus: z.ZodDefault<z.ZodEnum<{pending: "pending"; accepted: "accepted"... npmjs.com - Signature changed
cookies:getCookieCache
Was const getCookieCache: <S extends CookieCachePayload = CookieCachePayload>(request: Request | Headers, config?: {cookiePrefix?: string; cookieName?: string; isSecure?: boolean; secret?: string; strategy?: "compact" | "jwt" | "jwe"... npmjs.com - Signature changed
plugins:admin
Was const admin: <O extends AdminOptions>(options?: O | undefined) => {id: "admin"; version: string; init(): {options: {databaseHooks: {user: {create: {before(user: {id: string; createdAt: Date; updatedAt: Date; email: string... npmjs.com - Signature changed
plugins:UsernameOptions.schema.user
Was user: {fields: IncludeDisplayUsername extends false ? Pick<{username: {type: "string"; required: false; sortable: true; unique: true; returned: true; transform: {input(value: _$_better_auth_core_db0.DBPrimitive): string | number |... npmjs.com - Signature changed
plugins:UsernamePlugin.schema
Was schema: {user: {fields: IncludeDisplayUsername extends false ? Pick<{username: {type: "string"; required: false; sortable: true; unique: true; returned: true; transform: {input(value: _$_better_auth_core_db0.DBPrimitive): string |... npmjs.com
And 6 more in this version.
1.7.4
- Signature changed
plugins:TestHelpers.getAuthHeaders
Was getAuthHeaders(opts: {userId: string;}): Promise<Headers>; now getAuthHeaders(opts: TestAuthOptions): Promise<Headers>. npmjs.com - Signature changed
plugins:TestHelpers.getCookies
Was getCookies(opts: {userId: string; domain?: string;}): Promise<TestCookie[]>; now getCookies(opts: TestAuthOptions & {domain?: string;}): Promise<TestCookie[]>. npmjs.com - Signature changed
plugins:TestHelpers.login
Was login(opts: {userId: string;}): Promise<LoginResult>; now login(opts: TestAuthOptions): Promise<LoginResult>. npmjs.com
1.7.3
- Removed
plugins:GenericOAuthConfig.accountIssuer
GenericOAuthConfig.accountIssuer was removed in better-auth 1.7.3 npmjs.com - Behavior changed
Accounts are now looked up by (providerId, accountId) rather than issuer, restoring 1.6 account schema compatibility. Users who applied the 1.7 issuer schema should follow the upgrade guide cleanup. github.com - Default changed
Initialization now validates the database schema by default, including in production, and rejects authentication requests when a mismatch is detected. Users with mismatched schemas must fix them before requests succeed. github.com - Default changed
The Kysely adapter checks the live database schema by default and rejects authentication requests when it does not match. Users with mismatched schemas must fix them. github.com - Signature changed
api:accountInfo
Was const accountInfo: _$better_call0.StrictEndpoint<"/account-info", {method: "GET"; metadata: {openapi: {description: string; responses: {"200": {description: string; content: {"application/json": {schema: {type: "object"; properties... npmjs.com - Signature changed
api:getEndpoints
Was function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<AuthContext>, options: Option): {api: OverrideMerge<{readonly ok: _$better_call0.StrictEndpoint<"/ok", {method: "GET"; metadata: {openapi: {description: string... npmjs.com - Signature changed
api:linkSocialAccount
Was const linkSocialAccount: _$better_call0.StrictEndpoint<"/link-social", {method: "POST"; requireHeaders: true; body: z.ZodObject<{callbackURL: z.ZodOptional<z.ZodString>; provider: z.ZodType<(string & {}) | "linear" | "huggingface" |... npmjs.com - Signature changed
api:listUserAccounts
Was const listUserAccounts: _$better_call0.StrictEndpoint<"/list-accounts", {method: "GET"; use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext... npmjs.com - Signature changed
api:router
Was const router: <Option extends BetterAuthOptions>(ctx: AuthContext, options: Option) => {handler: (request: Request) => Promise<Response>; endpoints: UnionToIntersection<Option["plugins"] extends (infer T)[] ? T extends BetterAuthPlugin... npmjs.com - Signature changed
api:signInSocial
Was const signInSocial: <O extends BetterAuthOptions>() => _$better_call0.StrictEndpoint<"/sign-in/social", {method: "POST"; operationId: string; body: z.ZodObject<{callbackURL: z.ZodOptional<z.ZodString>; newUserCallbackURL... npmjs.com
And 10 more in this version.
1.7.2
- Behavior changed
Built-in placeholder emails are now generated in the namespaced {identifier}@{namespace}.placeholder.invalid format. Code that depends on the previous placeholder email format should be updated. github.com - Signature changed
client:AuthClient
Was type AuthClient<Option extends BetterAuthClientOptions> = UnionToIntersection<InferResolvedHooks<Option>> & InferClientAPI<Option> & InferActions<Option> & {hydrateSession: (session: NonNullable<ClientSession<Option>> | null) => void... npmjs.com - Signature changed
lynx:LynxAuthClient
Was type LynxAuthClient<Option extends BetterAuthClientOptions> = UnionToIntersection<InferResolvedHooks<Option>> & InferClientAPI<Option> & InferActions<Option> & {hydrateSession: (session: NonNullable<ClientSession<Option>> | null) =>... npmjs.com - Signature changed
react:ReactAuthClient
Was type ReactAuthClient<Option extends BetterAuthClientOptions> = UnionToIntersection<InferResolvedHooks<Option>> & InferClientAPI<Option> & InferActions<Option> & {hydrateSession: (session: NonNullable<ClientSession<Option>> | null) =>... npmjs.com - Signature changed
solid:SolidAuthClient
Was type SolidAuthClient<Option extends BetterAuthClientOptions> = UnionToIntersection<InferResolvedHooks<Option>> & InferClientAPI<Option> & InferActions<Option> & {hydrateSession: (session: NonNullable<ClientSession<Option>> | null) =>... npmjs.com - Signature changed
svelte:SvelteAuthClient
Was type SvelteAuthClient<Option extends BetterAuthClientOptions> = UnionToIntersection<InferResolvedHooks<Option>> & InferClientAPI<Option> & InferActions<Option> & {hydrateSession: (session: NonNullable<ClientSession<Option>> | null) =>... npmjs.com - Signature changed
test:getHttpTestInstance
Was function getHttpTestInstance<O extends Partial<BetterAuthOptions>, C extends BetterAuthClientOptions>(options?: O, config?: HttpTestInstanceConfig<C>): Promise<{server: HttpTestServer; baseURL: string; port: number; auth: Auth<O>... npmjs.com - Signature changed
vue:VueAuthClient
Was type VueAuthClient<Option extends BetterAuthClientOptions> = UnionToIntersection<InferResolvedHooks<Option>> & InferClientAPI<Option> & InferActions<Option> & {hydrateSession: (session: NonNullable<ClientSession<Option>> | null) =>... npmjs.com
Check your code
These are the changes. To see which of them reach your code, scan a public repository, or have your coding agent call check_code with your manifest or lockfile over MCP. The API reads every change in every version, not only the newest. On Team and up, a fix pull request opens for the changes that reach a connected repository. Nothing merges or deploys.

Put your code on continuous management.
Scan a public repository now, or give your agent one line.
See how out of date your code is.
Tell your agent what changed since it was trained.
claude mcp add --transport http since https://api.since.dev/mcp