deleteSessionCookie does not work if an ApiError is thrown #2734

Closed
opened 2026-03-13 10:16:14 -05:00 by GiteaMirror · 5 comments
Owner

Originally created by @mhamid3d on GitHub (Jan 19, 2026).

Originally assigned to: @himself65 on GitHub.

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Call deleteSessionCookie(ctx) from an api endpoint or middleware hook
  2. Throw an ApiError

Current vs. Expected behavior

Currently, if an ApiError (or any error) is thrown during a context lifecycle, cookies will not be added, removed, or modified for that error response. I expect the deleting cookies from a response to still work, even if that response is an error.

What version of Better Auth are you using?

1.4.15

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

Backend

Additional context

In a situation where you want to clear the session before throwing an error, the user still receives the session cookie. This would be used in a post authentication hook (such as two-factor), where the session is denied from advancing.

deleteSessionCookie(ctx, true);
throw new APIError("FORBIDDEN");
Originally created by @mhamid3d on GitHub (Jan 19, 2026). Originally assigned to: @himself65 on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Call `deleteSessionCookie(ctx)` from an api endpoint or middleware hook 2. Throw an ApiError ### Current vs. Expected behavior Currently, if an ApiError (or any error) is thrown during a context lifecycle, cookies will not be added, removed, or modified for that error response. I expect the deleting cookies from a response to still work, even if that response is an error. ### What version of Better Auth are you using? 1.4.15 ### Which area(s) are affected? (Select all that apply) Backend ### Additional context In a situation where you want to clear the session before throwing an error, the user still receives the session cookie. This would be used in a post authentication hook (such as two-factor), where the session is denied from advancing. ```typescript deleteSessionCookie(ctx, true); throw new APIError("FORBIDDEN"); ```
GiteaMirror added the bug label 2026-03-13 10:16:14 -05:00
Author
Owner

@better-auth-agent[bot] commented on GitHub (Jan 19, 2026):

It appears you've encountered an issue where deleteSessionCookie(ctx) does not work if an ApiError is thrown during a context lifecycle. The expected behavior is that cookies should still be modified, even when an error occurs.

This situation is noted as a problem in the current implementation, as throwing an error prevents cookie operations from being carried out. To address this, you might consider examining the error handling in your implementation, and checking if there have been any updates or patches related to deleteSessionCookie in recent versions, such as v1.4.15 you are using.

For now, it might be helpful to tag the Better Auth team members @bekacru and @ping__ for more precise guidance on this specific issue. They may offer insights or workarounds that better suit your use case.

Have you tried exploring error handling or debugging the specific points in the lifecycle where this error may affect cookie operations?

If you need more help, tag @better-auth-agent in a comment so I can respond.

DiagramDiscordGitHub

Diagram Join Star

@better-auth-agent[bot] commented on GitHub (Jan 19, 2026): It appears you've encountered an issue where `deleteSessionCookie(ctx)` does not work if an `ApiError` is thrown during a context lifecycle. The expected behavior is that cookies should still be modified, even when an error occurs. This situation is noted as a problem in the current implementation, as throwing an error prevents cookie operations from being carried out. To address this, you might consider examining the error handling in your implementation, and checking if there have been any updates or patches related to `deleteSessionCookie` in recent versions, such as v1.4.15 you are using. For now, it might be helpful to tag the Better Auth team members @bekacru and @ping__ for more precise guidance on this specific issue. They may offer insights or workarounds that better suit your use case. Have you tried exploring error handling or debugging the specific points in the lifecycle where this error may affect cookie operations? _If you need more help, tag @better-auth-agent in a comment so I can respond._ <!-- bot:webhook reply v1 --> [Diagram](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) • [Discord](https://discord.gg/better-auth) • [GitHub](https://github.com/better-auth/better-auth) [![Diagram](https://img.shields.io/badge/Diagram-2b3137?style=flat-square)](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) [![Join](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&style=flat-square)](https://discord.gg/better-auth) [![Star](https://img.shields.io/badge/star-181717?logo=github&logoColor=white&style=flat-square)](https://github.com/better-auth/better-auth)
Author
Owner

@dosubot[bot] commented on GitHub (Jan 19, 2026):

This is a known limitation in Better Auth v1.4.15: if you call deleteSessionCookie and then throw an ApiError, the framework's error handling overwrites any Set-Cookie headers scheduled before the exception, so cookie deletions do not reach the client in the error response. This happens because the error handling logic in toAuthEndpoints replaces the accumulated response headers (including Set-Cookie) with those from the error object, dropping any cookie modifications made earlier in the lifecycle. This behavior is confirmed by both code and issue discussions and is considered a bug or at least an unexpected limitation in v1.4.15 (source, source).

There is no built-in fix for this in v1.4.15. Workarounds are limited: you can try to restructure your error handling so that cookie deletions happen in successful responses, or catch errors before the response is finalized and manually set the appropriate headers. In some frameworks, you may also need to explicitly forward Set-Cookie headers in your middleware to ensure cookie changes reach the client (source).

Recent versions after v1.4.15 include improvements to cookie handling, but this specific issue with error responses and cookie deletion is not fully resolved in your version. If you need this functionality, consider tracking updates in newer releases or restructuring your flow to avoid relying on cookie deletion in error responses.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

@dosubot[bot] commented on GitHub (Jan 19, 2026): <!-- Answer --> This is a known limitation in Better Auth v1.4.15: if you call deleteSessionCookie and then throw an ApiError, the framework's error handling overwrites any Set-Cookie headers scheduled before the exception, so cookie deletions do not reach the client in the error response. This happens because the error handling logic in toAuthEndpoints replaces the accumulated response headers (including Set-Cookie) with those from the error object, dropping any cookie modifications made earlier in the lifecycle. This behavior is confirmed by both code and issue discussions and is considered a bug or at least an unexpected limitation in v1.4.15 ([source](https://github.com/better-auth/better-auth/blob/308f8ae14e3547c8f2ebf220a6e0cf96f0e42b87/packages/better-auth/src/api/to-auth-endpoints.ts#L45-L314), [source](https://github.com/better-auth/better-auth/issues/4983#issuecomment-3351570412)). There is no built-in fix for this in v1.4.15. Workarounds are limited: you can try to restructure your error handling so that cookie deletions happen in successful responses, or catch errors before the response is finalized and manually set the appropriate headers. In some frameworks, you may also need to explicitly forward Set-Cookie headers in your middleware to ensure cookie changes reach the client ([source](https://github.com/better-auth/better-auth/issues/4172#issuecomment-3216647681)). Recent versions after v1.4.15 include improvements to cookie handling, but this specific issue with error responses and cookie deletion is not fully resolved in your version. If you need this functionality, consider tracking updates in newer releases or restructuring your flow to avoid relying on cookie deletion in error responses. <!-- 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/92d1bb94-c46e-4dd5-8656-b3f8d5d06945?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/92d1bb94-c46e-4dd5-8656-b3f8d5d06945?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/92d1bb94-c46e-4dd5-8656-b3f8d5d06945?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/92d1bb94-c46e-4dd5-8656-b3f8d5d06945?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/92d1bb94-c46e-4dd5-8656-b3f8d5d06945?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/92d1bb94-c46e-4dd5-8656-b3f8d5d06945?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/92d1bb94-c46e-4dd5-8656-b3f8d5d06945?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20is%20a%20known%20limitation%20in%20Better%20Auth%20v1.4.15%3A%20if%20you%20call%20deleteSessionCookie%20and%20then%20throw%20an%20ApiError%2C%20the%20framework%27s%20error%20handling%20overwrites%20any%20Set-Cookie%20headers%20scheduled%20before%20the%20exception%2C%20so%20cookie%20deletions%20do%20not%20reach%20the%20client%20in%20the%20error%20response.%20This%20happens%20because%20the%20error%20handling%20logic%20in%20toAuthEndpoints%20replaces%20the%20accumulated%20response%20headers%20%28including%20Set-Cookie%29%20with%20those%20from%20the%20error%20object%2C%20dropping%20any%20cookie%20modifications%20made%20earlier%20in%20the%20lifecycle.%20This%20behavior%20is%20confirmed%20by%20both%20code%20and%20issue%20discussions%20and%20is%20considered%20a%20bug%20or%20at%20least%20an%20unexpected%20limitation%20in%20v1.4.15%20%28%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/blob/308f8ae14e3547c8f2ebf220a6e0cf96f0e42b87/packages/better-auth/src/api/to-auth-endpoints.ts%23L45-L314%29%2C%20%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/4983%23issuecomment-3351570412%29%29.%0A%0AThere%20is%20no%20built-in%20fix%20for%20this%20in%20v1.4.15.%20Workarounds%20are%20limited%3A%20you%20can%20try%20to%20restructure%20your%20error%20handling%20so%20that%20cookie%20deletions%20happen%20in%20successful%20responses%2C%20or%20catch%20errors%20before%20the%20response%20is%20finalized%20and%20manually%20set%20the%20appropriate%20headers.%20In%20some%20frameworks%2C%20you%20may%20also%20need%20to%20explicitly%20forward%20Set-Cookie%20headers%20in%20your%20middleware%20to%20ensure%20cookie%20changes%20reach%20the%20client%20%28%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/4172%23issuecomment-3216647681%29%29.%0A%0ARecent%20versions%20after%20v1.4.15%20include%20improvements%20to%20cookie%20handling%2C%20but%20this%20specific%20issue%20with%20error%20responses%20and%20cookie%20deletion%20is%20not%20fully%20resolved%20in%20your%20version.%20If%20you%20need%20this%20functionality%2C%20consider%20tracking%20updates%20in%20newer%20releases%20or%20restructuring%20your%20flow%20to%20avoid%20relying%20on%20cookie%20deletion%20in%20error%20responses.)&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/7473)
Author
Owner

@mhamid3d commented on GitHub (Jan 19, 2026):

I will note that another issue mentioned this, but dosubot and @himself65 said that deleteSessionCookie was the fix. However this doesn't seem to be the case. It also explains why in the two-factor plugin, a successful response is being sent instead of an error response.

@mhamid3d commented on GitHub (Jan 19, 2026): I will note that [another issue](https://github.com/better-auth/better-auth/issues/4983) mentioned this, but dosubot and @himself65 said that `deleteSessionCookie` was the fix. However this doesn't seem to be the case. It also explains why in the two-factor plugin, a successful response is being sent instead of an error response.
Author
Owner

@dosubot[bot] commented on GitHub (Jan 19, 2026):

You're right—calling deleteSessionCookie before throwing an ApiError does not reliably clear cookies in error responses in Better Auth v1.4.15. The technical reason is that when an ApiError is thrown, the framework's error handling replaces all previously set response headers (including Set-Cookie) with those from the error object, so any cookie deletions are lost and never reach the client. This is confirmed by both the code and issue discussions, including #4983, and is especially problematic in Next.js and after hooks where the cookie cache may be disabled or the Next.js cookies API may not be available or reliable for this purpose [source][source][source].

That's why the two-factor plugin and similar flows use a workaround: they send a successful response (like ctx.json) after updating or deleting cookies, rather than throwing an error, to ensure the cookie changes are actually sent to the client [source][source]. This is currently the only reliable way to clear cookies in these scenarios.

The advice to use deleteSessionCookie was based on the intended API, but in practice, due to the error handling design, it doesn't work as expected in error responses. There are improvements in newer versions, but this specific limitation still exists in v1.4.15. For now, structuring your flow to avoid throwing errors after deleting cookies (and instead returning a response) is the most reliable pattern.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

@dosubot[bot] commented on GitHub (Jan 19, 2026): <!-- Answer --> You're right—calling deleteSessionCookie before throwing an ApiError does not reliably clear cookies in error responses in Better Auth v1.4.15. The technical reason is that when an ApiError is thrown, the framework's error handling replaces all previously set response headers (including Set-Cookie) with those from the error object, so any cookie deletions are lost and never reach the client. This is confirmed by both the code and issue discussions, including #4983, and is especially problematic in Next.js and after hooks where the cookie cache may be disabled or the Next.js cookies API may not be available or reliable for this purpose [[source](https://github.com/better-auth/better-auth/issues/4983)][[source](https://github.com/better-auth/better-auth/blob/308f8ae14e3547c8f2ebf220a6e0cf96f0e42b87/packages/better-auth/src/api/to-auth-endpoints.ts#L45-L315)][[source](https://github.com/better-auth/better-auth/blob/308f8ae14e3547c8f2ebf220a6e0cf96f0e42b87/packages/better-auth/src/integrations/next-js.ts#L24-L85)]. That's why the two-factor plugin and similar flows use a workaround: they send a successful response (like ctx.json) after updating or deleting cookies, rather than throwing an error, to ensure the cookie changes are actually sent to the client [[source](https://github.com/better-auth/better-auth/issues/1104)][[source](https://github.com/better-auth/better-auth/issues/6077)]. This is currently the only reliable way to clear cookies in these scenarios. The advice to use deleteSessionCookie was based on the intended API, but in practice, due to the error handling design, it doesn't work as expected in error responses. There are improvements in newer versions, but this specific limitation still exists in v1.4.15. For now, structuring your flow to avoid throwing errors after deleting cookies (and instead returning a response) is the most reliable pattern. <!-- 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/3d683bc3-2373-4ba7-99cc-95c8fadbd47a?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/3d683bc3-2373-4ba7-99cc-95c8fadbd47a?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/3d683bc3-2373-4ba7-99cc-95c8fadbd47a?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/3d683bc3-2373-4ba7-99cc-95c8fadbd47a?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/3d683bc3-2373-4ba7-99cc-95c8fadbd47a?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/3d683bc3-2373-4ba7-99cc-95c8fadbd47a?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/3d683bc3-2373-4ba7-99cc-95c8fadbd47a?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=You%27re%20right%E2%80%94calling%20deleteSessionCookie%20before%20throwing%20an%20ApiError%20does%20not%20reliably%20clear%20cookies%20in%20error%20responses%20in%20Better%20Auth%20v1.4.15.%20The%20technical%20reason%20is%20that%20when%20an%20ApiError%20is%20thrown%2C%20the%20framework%27s%20error%20handling%20replaces%20all%20previously%20set%20response%20headers%20%28including%20Set-Cookie%29%20with%20those%20from%20the%20error%20object%2C%20so%20any%20cookie%20deletions%20are%20lost%20and%20never%20reach%20the%20client.%20This%20is%20confirmed%20by%20both%20the%20code%20and%20issue%20discussions%2C%20including%20%234983%2C%20and%20is%20especially%20problematic%20in%20Next.js%20and%20after%20hooks%20where%20the%20cookie%20cache%20may%20be%20disabled%20or%20the%20Next.js%20cookies%20API%20may%20not%20be%20available%20or%20reliable%20for%20this%20purpose%20%5B%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/4983%29%5D%5B%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/blob/308f8ae14e3547c8f2ebf220a6e0cf96f0e42b87/packages/better-auth/src/api/to-auth-endpoints.ts%23L45-L315%29%5D%5B%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/blob/308f8ae14e3547c8f2ebf220a6e0cf96f0e42b87/packages/better-auth/src/integrations/next-js.ts%23L24-L85%29%5D.%0A%0AThat%27s%20why%20the%20two-factor%20plugin%20and%20similar%20flows%20use%20a%20workaround%3A%20they%20send%20a%20successful%20response%20%28like%20ctx.json%29%20after%20updating%20or%20deleting%20cookies%2C%20rather%20than%20throwing%20an%20error%2C%20to%20ensure%20the%20cookie%20changes%20are%20actually%20sent%20to%20the%20client%20%5B%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/1104%29%5D%5B%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/6077%29%5D.%20This%20is%20currently%20the%20only%20reliable%20way%20to%20clear%20cookies%20in%20these%20scenarios.%0A%0AThe%20advice%20to%20use%20deleteSessionCookie%20was%20based%20on%20the%20intended%20API%2C%20but%20in%20practice%2C%20due%20to%20the%20error%20handling%20design%2C%20it%20doesn%27t%20work%20as%20expected%20in%20error%20responses.%20There%20are%20improvements%20in%20newer%20versions%2C%20but%20this%20specific%20limitation%20still%20exists%20in%20v1.4.15.%20For%20now%2C%20structuring%20your%20flow%20to%20avoid%20throwing%20errors%20after%20deleting%20cookies%20%28and%20instead%20returning%20a%20response%29%20is%20the%20most%20reliable%20pattern.)&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/7473)
Author
Owner

@himself65 commented on GitHub (Jan 20, 2026):

Hi, I'm checking this

@himself65 commented on GitHub (Jan 20, 2026): Hi, I'm checking this
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#2734