Twitter login does not work after 1.3.0-beta9 or newer #1532

Closed
opened 2026-03-13 08:45:40 -05:00 by GiteaMirror · 14 comments
Owner

Originally created by @Re4GD on GitHub (Jul 19, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Upgrade to 1.3.0-beta9 or newer, Twitter login does not work

Current vs. Expected behavior

Try Twitter login in 1.3.0-beta8, works fine.

After 1.3.0-beta9 (including 1.3.0 release), cannot login with Twitter. Error:

2025-07-19T20:43:03.070Z ERROR [Better Auth]:  {
  error: 'invalid_request',
  error_description: 'Missing required parameter [client_id].',
  status: 400,
  statusText: 'Bad Request'
}

What version of Better Auth are you using?

1.3.0-beta9

Provide environment information

- OS: Arch Linux
- Browser: Chrome

Which area(s) are affected? (Select all that apply)

Backend, Package

Auth config (if applicable)

import { betterAuth } from "better-auth"
import { env } from "./env";

export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
  socialProviders: {
    twitter: {
      clientId: env.AUTH_TWITTER_CLIENT_ID,
      clientSecret: env.AUTH_TWITTER_CLIENT_SECRET,
    },
  },
});

Additional context

Google sign in works in both beta8 and beta9.

Twitter works correctly in beta8, starts giving error after beta9:

2025-07-19T20:43:03.070Z ERROR [Better Auth]:  {
  error: 'invalid_request',
  error_description: 'Missing required parameter [client_id].',
  status: 400,
  statusText: 'Bad Request'
}

The error originates from packages/better-auth/src/api/routes/callback.ts, L92

let tokens: OAuth2Tokens;
try {
	tokens = await provider.validateAuthorizationCode({
		code: code,
		codeVerifier,
		deviceId: device_id,
		redirectURI: `${c.context.baseURL}/callback/${provider.id}`,
	});
} catch (e) {
	c.context.logger.error("", e);
	throw redirectOnError("invalid_code");
}

I compared beta8 and beta9, https://github.com/better-auth/better-auth/compare/v1.3.0-beta.8...v1.3.0-beta.9. When I searched for validateAuthorizationCode, I came across this commit 7364c169f6. In this commit it says - This change enhances compatibility with providers like Notion and Twitter, adhering to OAuth2 specifications (RFC 7617)..

I suspect there is a mismatch in the current base64 parameter verification, or in validateAuthorizationCode.

Image
Originally created by @Re4GD on GitHub (Jul 19, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Upgrade to 1.3.0-beta9 or newer, Twitter login does not work ### Current vs. Expected behavior Try Twitter login in 1.3.0-beta8, works fine. After 1.3.0-beta9 (including 1.3.0 release), cannot login with Twitter. Error: ``` 2025-07-19T20:43:03.070Z ERROR [Better Auth]: { error: 'invalid_request', error_description: 'Missing required parameter [client_id].', status: 400, statusText: 'Bad Request' } ``` ### What version of Better Auth are you using? 1.3.0-beta9 ### Provide environment information ```bash - OS: Arch Linux - Browser: Chrome ``` ### Which area(s) are affected? (Select all that apply) Backend, Package ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" import { env } from "./env"; export const auth = betterAuth({ emailAndPassword: { enabled: true }, socialProviders: { twitter: { clientId: env.AUTH_TWITTER_CLIENT_ID, clientSecret: env.AUTH_TWITTER_CLIENT_SECRET, }, }, }); ``` ### Additional context Google sign in works in both beta8 and beta9. Twitter works correctly in beta8, starts giving error after beta9: ``` 2025-07-19T20:43:03.070Z ERROR [Better Auth]: { error: 'invalid_request', error_description: 'Missing required parameter [client_id].', status: 400, statusText: 'Bad Request' } ``` --- The error originates from `packages/better-auth/src/api/routes/callback.ts`, L92 ``` let tokens: OAuth2Tokens; try { tokens = await provider.validateAuthorizationCode({ code: code, codeVerifier, deviceId: device_id, redirectURI: `${c.context.baseURL}/callback/${provider.id}`, }); } catch (e) { c.context.logger.error("", e); throw redirectOnError("invalid_code"); } ``` --- I compared beta8 and beta9, https://github.com/better-auth/better-auth/compare/v1.3.0-beta.8...v1.3.0-beta.9. When I searched for `validateAuthorizationCode`, I came across this commit https://github.com/better-auth/better-auth/commit/7364c169f6de0eec4f095112047e23480b240078. In this commit it says `- This change enhances compatibility with providers like Notion and Twitter, adhering to OAuth2 specifications (RFC 7617).`. I suspect there is a mismatch in the current base64 parameter verification, or in validateAuthorizationCode. <img width="530" height="499" alt="Image" src="https://github.com/user-attachments/assets/0a5db4c2-f621-4c6c-acb3-5137c8b86e41" />
GiteaMirror added the bug label 2026-03-13 08:45:40 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jul 19, 2025):

Hi @Re4GD! I'm Dosu and I’m helping the better-auth team.

This is a regression caused by a change in how Better Auth handles OAuth2 authentication for Twitter starting in 1.3.0-beta9. The library now sends client credentials using HTTP Basic Auth (in the Authorization header), but Twitter requires them in the POST body. This results in the "Missing required parameter [client_id]" error you’re seeing.

The Twitter provider is currently hardcoded to use the "basic" authentication method and does not expose an option in user config to switch to "body" authentication. Fixing this requires modifying the provider code itself to set authentication: "body" in the validateAuthorizationCode call. There’s no workaround available in user config at this time—this is a library-level issue and not something you can patch from your app config.
Reference

To restore Twitter login, you’ll need to fork the repo and change the Twitter provider’s validateAuthorizationCode to use authentication: "body" instead of "basic". Alternatively, maintainers should update the provider definition to set this by default or expose it as a user-configurable option in a future release.

Let me know if you want a code snippet or step-by-step for patching the provider!

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

@dosubot[bot] commented on GitHub (Jul 19, 2025): <!-- Greeting --> Hi @Re4GD! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a regression caused by a change in how Better Auth handles OAuth2 authentication for Twitter starting in 1.3.0-beta9. The library now sends client credentials using HTTP Basic Auth (in the Authorization header), but Twitter requires them in the POST body. This results in the "Missing required parameter [client_id]" error you’re seeing. The Twitter provider is currently hardcoded to use the "basic" authentication method and does not expose an option in user config to switch to "body" authentication. Fixing this requires modifying the provider code itself to set authentication: "body" in the validateAuthorizationCode call. There’s no workaround available in user config at this time—this is a library-level issue and not something you can patch from your app config. [Reference](https://github.com/better-auth/better-auth/blob/79629fa3514a13ed2851bc1a83d11249539a2d22/packages/better-auth/src/social-providers/twitter.ts) To restore Twitter login, you’ll need to fork the repo and change the Twitter provider’s validateAuthorizationCode to use authentication: "body" instead of "basic". Alternatively, maintainers should update the provider definition to set this by default or expose it as a user-configurable option in a future release. Let me know if you want a code snippet or step-by-step for patching the provider! <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/4d60d8c4-b593-4c54-a0a8-301fda915d92?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/4d60d8c4-b593-4c54-a0a8-301fda915d92?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/4d60d8c4-b593-4c54-a0a8-301fda915d92?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/4d60d8c4-b593-4c54-a0a8-301fda915d92?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/4d60d8c4-b593-4c54-a0a8-301fda915d92?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/4d60d8c4-b593-4c54-a0a8-301fda915d92?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/4d60d8c4-b593-4c54-a0a8-301fda915d92?feedback_type=other)</sup>&nbsp;&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/3481)
Author
Owner

@Re4GD commented on GitHub (Jul 19, 2025):

@dosubot I would like patch steps

@Re4GD commented on GitHub (Jul 19, 2025): @dosubot I would like patch steps
Author
Owner

@dosubot[bot] commented on GitHub (Jul 19, 2025):

Here’s how to patch Better Auth so Twitter login works again:

  1. Open packages/better-auth/src/social-providers/twitter.ts in your local or forked copy.
  2. Find the validateAuthorizationCode function. Inside, you’ll see a call like:
    return validateAuthorizationCode({
      code,
      codeVerifier,
      authentication: "basic", // <-- change this line
      redirectURI,
      options,
      tokenEndpoint: "https://api.x.com/2/oauth2/token",
    });
    
  3. Change authentication: "basic" to authentication: "body".
  4. Save the file.
  5. Rebuild the package (e.g., pnpm build or npm run build).
  6. If you’re using a local fork, reinstall the rebuilt package in your app (e.g., npm install ../path-to-better-auth).
  7. Restart your app and test Twitter login.

If you still see issues, try clearing your app’s cache and lockfiles.
Reference: twitter.ts implementation

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

@dosubot[bot] commented on GitHub (Jul 19, 2025): <!-- Answer --> Here’s how to patch Better Auth so Twitter login works again: 1. Open packages/better-auth/src/social-providers/twitter.ts in your local or forked copy. 2. Find the validateAuthorizationCode function. Inside, you’ll see a call like: ```ts return validateAuthorizationCode({ code, codeVerifier, authentication: "basic", // <-- change this line redirectURI, options, tokenEndpoint: "https://api.x.com/2/oauth2/token", }); ``` 3. Change authentication: "basic" to authentication: "body". 4. Save the file. 5. Rebuild the package (e.g., pnpm build or npm run build). 6. If you’re using a local fork, reinstall the rebuilt package in your app (e.g., npm install ../path-to-better-auth). 7. Restart your app and test Twitter login. If you still see issues, try clearing your app’s cache and lockfiles. Reference: [twitter.ts implementation](https://github.com/better-auth/better-auth/blob/79629fa3514a13ed2851bc1a83d11249539a2d22/packages/better-auth/src/social-providers/twitter.ts) <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/d8906992-4005-4c6b-9b45-82e2bf6a2e67?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/d8906992-4005-4c6b-9b45-82e2bf6a2e67?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/d8906992-4005-4c6b-9b45-82e2bf6a2e67?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/d8906992-4005-4c6b-9b45-82e2bf6a2e67?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/d8906992-4005-4c6b-9b45-82e2bf6a2e67?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/d8906992-4005-4c6b-9b45-82e2bf6a2e67?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/d8906992-4005-4c6b-9b45-82e2bf6a2e67?feedback_type=other)</sup>&nbsp;&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/3481)
Author
Owner

@Re4GD commented on GitHub (Jul 19, 2025):

@Bekacru @Kinfe123 @dagmawibabi Currently there is no way to use Twitter social login. I am stuck in 1.3.0-beta8 because of this. Is there a workaround? If there is no workaround like dosubot said, can you guys make a patch release as this affects the current 1.3.0 release for major social providers

@Re4GD commented on GitHub (Jul 19, 2025): @Bekacru @Kinfe123 @dagmawibabi Currently there is no way to use Twitter social login. I am stuck in 1.3.0-beta8 because of this. Is there a workaround? If there is no workaround like dosubot said, can you guys make a patch release as this affects the current 1.3.0 release for major social providers
Author
Owner

@dagmawibabi commented on GitHub (Jul 19, 2025):

Hey @Re4GD making a patch PR now

@dagmawibabi commented on GitHub (Jul 19, 2025): Hey @Re4GD making a patch PR now
Author
Owner

@dagmawibabi commented on GitHub (Jul 19, 2025):

@Re4GD patch merged, kindly try it out and let us know :)

@dagmawibabi commented on GitHub (Jul 19, 2025): @Re4GD patch merged, kindly try it out and let us know :)
Author
Owner

@Re4GD commented on GitHub (Jul 20, 2025):

@dagmawibabi Still happening in 1.3.1: Error Code: invalid_code. However the error has changed:

2025-07-20T06:55:28.555Z ERROR [Better Auth]:  {
  error: 'unauthorized_client',
  error_description: 'Missing valid authorization header',
  status: 401,
  statusText: 'Unauthorized'
}
Image
@Re4GD commented on GitHub (Jul 20, 2025): @dagmawibabi Still happening in 1.3.1: `Error Code: invalid_code`. However the error has changed: ``` 2025-07-20T06:55:28.555Z ERROR [Better Auth]: { error: 'unauthorized_client', error_description: 'Missing valid authorization header', status: 401, statusText: 'Unauthorized' } ``` <img width="529" height="478" alt="Image" src="https://github.com/user-attachments/assets/8044441b-4240-4eeb-9871-d6793133596b" />
Author
Owner

@Re4GD commented on GitHub (Jul 20, 2025):

I think the library needs E2E tests with playwright to verify these oauth flows. Small changes in the twitter code to better follow the specifications made the whole Twitter login completely unusable.

@Re4GD commented on GitHub (Jul 20, 2025): I think the library needs E2E tests with playwright to verify these oauth flows. Small changes in the twitter code to better follow the specifications made the whole Twitter login completely unusable.
Author
Owner

@Re4GD commented on GitHub (Jul 20, 2025):

@dagmawibabi Hi, have you had a chance to take a look?

@Re4GD commented on GitHub (Jul 20, 2025): @dagmawibabi Hi, have you had a chance to take a look?
Author
Owner

@Kinfe123 commented on GitHub (Jul 20, 2025):

it is not about the latter change introduce on commit that you mentioned. It is more of X being strict on handing this. For PKCE, only client_id should be sent in the body, no client_secret or Authorization header. For confidential clients, client_secret must be sent by Authorization: Basic base64(client_id:client_secret), not in the body and including the client secret in the body and passing the auth header is not allowed so Including both in the body will result in a Missing valid authorization header error.

@Kinfe123 commented on GitHub (Jul 20, 2025): it is not about the latter change introduce on commit that you mentioned. It is more of X being strict on handing this. For PKCE, only client_id should be sent in the body, no client_secret or Authorization header. For confidential clients, client_secret must be sent by Authorization: Basic base64(client_id:client_secret), not in the body and including the client secret in the body and passing the auth header is not allowed so Including both in the body will result in a Missing valid authorization header error.
Author
Owner

@Kinfe123 commented on GitHub (Jul 20, 2025):

for now can you try installing this after restarting your dev server and cleaning up stuff just to make sure.

npm i https://pkg.pr.new/better-auth/better-auth@3510
@Kinfe123 commented on GitHub (Jul 20, 2025): for now can you try installing this after restarting your dev server and cleaning up stuff just to make sure. ``` npm i https://pkg.pr.new/better-auth/better-auth@3510 ```
Author
Owner

@Re4GD commented on GitHub (Jul 21, 2025):

@Kinfe123 Got it, thank you. The package link you sent is working, both in dev and prod for Twitter login.

I like to follow the latest releases including beta tags to test out the new features. Will this issue be completely gone in the following releases?

@Re4GD commented on GitHub (Jul 21, 2025): @Kinfe123 Got it, thank you. The package link you sent is working, both in dev and prod for Twitter login. I like to follow the latest releases including beta tags to test out the new features. Will this issue be completely gone in the following releases?
Author
Owner

@Kinfe123 commented on GitHub (Jul 21, 2025):

Yeah. It will be released soon.

@Kinfe123 commented on GitHub (Jul 21, 2025): Yeah. It will be released soon.
Author
Owner

@Re4GD commented on GitHub (Jul 27, 2025):

@Kinfe123 Hi, has this issue been resolved in the latest releases? I haven't seen anything about it in the changelogs. I am still using the package you sent

@Re4GD commented on GitHub (Jul 27, 2025): @Kinfe123 Hi, has this issue been resolved in the latest releases? I haven't seen anything about it in the changelogs. I am still using the package you sent
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1532