[GH-ISSUE #599] Sign up request getting stuck #8334

Closed
opened 2026-04-13 03:24:12 -05:00 by GiteaMirror · 6 comments
Owner

Originally created by @lindesvard on GitHub (Nov 19, 2024).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/599

Describe the bug
Sign up request getting stuck similar to this issue https://github.com/better-auth/better-auth/issues/320

I suspect something similar to this is the issue. But have removed everything except fastify cors and better-auth routes without luck.

To Reproduce

    const fastify = Fastify({});
    fastify.register(cors, {
      origin: ['http://localhost:3000'],
      credentials: true,
    });
    fastify.all('/auth/*', (req, res) => {
      return toNodeHandler(auth)(req.raw, res.raw);
    });
    await fastify.listen({
      port,
    });
export const auth = betterAuth({
  database: prismaAdapter(db, {
    provider: 'postgresql',
  }),
  baseURL: `${process.env.NEXT_PUBLIC_API_URL}/auth`,
  logger: {
    level: 'debug',
  },
  trustedOrigins: ['http://localhost:3000', 'http://localhost:3333'],
  emailAndPassword: {
    enabled: true,
  },
});
  1. Using signUp method
  2. Request get stalled

Expected behavior
The request should return 200 or any other status

Screenshots
image

Desktop (please complete the following information):

  • OS: MacOS 14.6.1
  • Browser Chrome

Additional info

The logger does not seem to work since I don't get any logs (atleast not for sign up, /auth/get-session or /auth/ok requests)

Originally created by @lindesvard on GitHub (Nov 19, 2024). Original GitHub issue: https://github.com/better-auth/better-auth/issues/599 **Describe the bug** Sign up request getting stuck similar to this issue https://github.com/better-auth/better-auth/issues/320 I suspect something similar to [this](https://github.com/better-auth/better-auth/issues/320#issuecomment-2434543200) is the issue. But have removed everything except fastify cors and better-auth routes without luck. **To Reproduce** ``` const fastify = Fastify({}); fastify.register(cors, { origin: ['http://localhost:3000'], credentials: true, }); fastify.all('/auth/*', (req, res) => { return toNodeHandler(auth)(req.raw, res.raw); }); await fastify.listen({ port, }); ``` ``` export const auth = betterAuth({ database: prismaAdapter(db, { provider: 'postgresql', }), baseURL: `${process.env.NEXT_PUBLIC_API_URL}/auth`, logger: { level: 'debug', }, trustedOrigins: ['http://localhost:3000', 'http://localhost:3333'], emailAndPassword: { enabled: true, }, }); ``` 1. Using `signUp` method 2. Request get stalled **Expected behavior** The request should return 200 or any other status **Screenshots** ![image](https://github.com/user-attachments/assets/b36911a8-a5eb-462e-be63-eb4d9e7695f5) **Desktop (please complete the following information):** - OS: MacOS 14.6.1 - Browser Chrome ## Additional info The logger does not seem to work since I don't get any logs (atleast not for sign up, `/auth/get-session` or `/auth/ok` requests)
GiteaMirror added the locked label 2026-04-13 03:24:12 -05:00
Author
Owner

@lindesvard commented on GitHub (Nov 20, 2024):

Attempt 2

Tried to use fastify-standard-request-reply to convert req and reply to Request and Response. No stalled request but I get errors that email is invalid. I assume the body is not picked up.

import cors from '@fastify/cors';
import { auth } from '@repo/auth/server/auth';
import Fastify from 'fastify';

import {
  createStandardRequest,
  sendStandardResponse,
} from 'fastify-standard-request-reply';

const startServer = async () => {
  try {
    const fastify = Fastify({});
    fastify.register(cors, {
      origin: ['http://localhost:3000'],
      credentials: true,
    });
    fastify.all('/auth/*', async (req, reply) => {
      const request = createStandardRequest(req, reply);
      const response = await auth.handler(request);
      await sendStandardResponse(reply, response);
    });
    await fastify.listen({
      port: 3333,
    });
  } catch (error) {
    console.log('Sad hest');
  }
};

startServer();
<!-- gh-comment-id:2488420465 --> @lindesvard commented on GitHub (Nov 20, 2024): ## Attempt 2 Tried to use `fastify-standard-request-reply` to convert req and reply to `Request` and `Response`. No stalled request but I get errors that `email` is invalid. I assume the body is not picked up. ``` import cors from '@fastify/cors'; import { auth } from '@repo/auth/server/auth'; import Fastify from 'fastify'; import { createStandardRequest, sendStandardResponse, } from 'fastify-standard-request-reply'; const startServer = async () => { try { const fastify = Fastify({}); fastify.register(cors, { origin: ['http://localhost:3000'], credentials: true, }); fastify.all('/auth/*', async (req, reply) => { const request = createStandardRequest(req, reply); const response = await auth.handler(request); await sendStandardResponse(reply, response); }); await fastify.listen({ port: 3333, }); } catch (error) { console.log('Sad hest'); } }; startServer(); ```
Author
Owner

@scalebearx commented on GitHub (Nov 21, 2024):

me with express got stucked too, lol

<!-- gh-comment-id:2490256641 --> @scalebearx commented on GitHub (Nov 21, 2024): me with express got stucked too, lol
Author
Owner

@rhyek commented on GitHub (Dec 8, 2024):

I was getting the same behavior with a fastify app. In my case I tracked it down to this line in a dependency: 53df74c594/src/utils.ts (L31)
It just hangs there for me when trying to send magic links.

Decided to just spin up a separate express app just for this lib. It worked there immediately.

<!-- gh-comment-id:2525361463 --> @rhyek commented on GitHub (Dec 8, 2024): I was getting the same behavior with a fastify app. In my case I tracked it down to this line in a dependency: https://github.com/Bekacru/better-call/blob/53df74c594cb4f6ed557f3a7a59a2effa7806b30/src/utils.ts#L31 It just hangs there for me when trying to send magic links. Decided to just spin up a separate express app just for this lib. It worked there immediately.
Author
Owner

@richard-better commented on GitHub (Dec 20, 2024):

What worked for me is stopping fastify from consuming the body in the first place.

await fastify.register((fastify) => {
  const authhandler = toNodeHandler(auth);

  fastify.addContentTypeParser(
    "application/json",
    (_request, _payload, done) => {
      done(null, null);
    },
  );

  fastify.all("/api/auth/*", async (request, reply) => {
    await authhandler(request.raw, reply.raw);
  });
});

addContentTypeParser allows you to define a custom parser for the body, and by not consuming the stream, better-call can read it later.

The code itself is inside a fastify plugin (added via a register call) to make sure all your other routes can still read the body.

<!-- gh-comment-id:2557799177 --> @richard-better commented on GitHub (Dec 20, 2024): What worked for me is stopping fastify from consuming the body in the first place. ```typescript await fastify.register((fastify) => { const authhandler = toNodeHandler(auth); fastify.addContentTypeParser( "application/json", (_request, _payload, done) => { done(null, null); }, ); fastify.all("/api/auth/*", async (request, reply) => { await authhandler(request.raw, reply.raw); }); }); ``` `addContentTypeParser` allows you to define a custom parser for the body, and by not consuming the stream, `better-call` can read it later. The code itself is inside a fastify plugin (added via a `register` call) to make sure all your other routes can still read the body.
Author
Owner

@lindesvard commented on GitHub (Dec 20, 2024):

Rolled my own auth in the end but this is great. Hope to give this library another shot for another project!

<!-- gh-comment-id:2557846242 --> @lindesvard commented on GitHub (Dec 20, 2024): Rolled my own auth in the end but this is great. Hope to give this library another shot for another project!
Author
Owner

@brandonwisnicki commented on GitHub (Jan 19, 2025):

Building on @richard-better's solution, I was also interested in getting CORs working using fastify-cors, but it seems like fastify-cors does not write to the raw body that better-auth uses to send back to the client, so I manually wrote it to the raw body before the auth handler is called.


if (process.env.CORS_ORIGIN != null) {
    const corsOption = {
        origin: [process.env.CORS_ORIGIN],
        credentials: true,
    };
    await server.register(cors, corsOption);
}

await server.register(async (fastify) => {
    const authhandler = toNodeHandler(auth);
    fastify.addContentTypeParser(
        'application/json',
        (_request, _payload, done) => {
            done(null, null);
        }
    );
    fastify.all('/api/auth/*', async (request, reply) => {
        reply.raw.setHeaders(headersRecordToMap(reply.getHeaders()));

        await authhandler(request.raw, reply.raw);
    });
});

And to convert the record to the map in a typesafe way

import type { HttpHeader } from 'fastify/types/utils';

export const headersRecordToMap = (
    headers: Record<HttpHeader, string | number | string[] | undefined>
) => {
    const entries = Object.entries(headers);
    const map: Map<string, number | string | readonly string[]> = new Map();
    for (const [headerKey, headerValue] of entries) {
        if (headerValue != null) {
            map.set(headerKey, headerValue);
        }
    }
    return map;
};

<!-- gh-comment-id:2601013302 --> @brandonwisnicki commented on GitHub (Jan 19, 2025): Building on @richard-better's solution, I was also interested in getting CORs working using fastify-cors, but it seems like fastify-cors does not write to the raw body that better-auth uses to send back to the client, so I manually wrote it to the raw body before the auth handler is called. ```ts if (process.env.CORS_ORIGIN != null) { const corsOption = { origin: [process.env.CORS_ORIGIN], credentials: true, }; await server.register(cors, corsOption); } await server.register(async (fastify) => { const authhandler = toNodeHandler(auth); fastify.addContentTypeParser( 'application/json', (_request, _payload, done) => { done(null, null); } ); fastify.all('/api/auth/*', async (request, reply) => { reply.raw.setHeaders(headersRecordToMap(reply.getHeaders())); await authhandler(request.raw, reply.raw); }); }); ``` And to convert the record to the map in a typesafe way ```ts import type { HttpHeader } from 'fastify/types/utils'; export const headersRecordToMap = ( headers: Record<HttpHeader, string | number | string[] | undefined> ) => { const entries = Object.entries(headers); const map: Map<string, number | string | readonly string[]> = new Map(); for (const [headerKey, headerValue] of entries) { if (headerValue != null) { map.set(headerKey, headerValue); } } return map; }; ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#8334