Skip to content

fix: friendly message for expired/used magic-link errors - #57

Merged
mroderick merged 2 commits into
mainfrom
fix/friendlier-magic-link-error
Aug 6, 2026
Merged

fix: friendly message for expired/used magic-link errors#57
mroderick merged 2 commits into
mainfrom
fix/friendlier-magic-link-error

Conversation

@mroderick

@mroderick mroderick commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Problem

Reusing an already-used magic link (or clicking an expired one) showed the raw error INVALID_TOKEN on the login page — not user-friendly.

CleanShot 2026-07-28 at 14 43 41

Root cause

The raw code isn't from our code. Better Auth's magic-link plugin consumes (deletes) the token on verification; for a reused/expired link the token is already gone, so it calls redirectWithError("INVALID_TOKEN") (better-auth source). That helper does errorCallbackURL.searchParams.set("error", "INVALID_TOKEN"), overwriting whatever message we previously embedded in errorCallbackURL. So our wording never reached the user.

Fix

Map Better Auth error codes to human-friendly text at render time, independent of what code Better Auth sends:

  • src/app/utils/friendly-error.js — new friendlyError(code) mapping INVALID_TOKEN (and a few siblings) to plain sentences; unknown codes pass through unchanged.
  • src/app/routes/auth.js — apply the mapping in showLogin and showMagicLinkForm, and drop the now-dead embedded message from errorCallbackURL (its /login destination is still required).

INVALID_TOKEN now renders as: "This sign-in link has expired or already been used. Please request a new one."

Tests

  • test/unit/friendly-error.test.js: mapping covers known codes, passes through unknown.
  • Route test: /login?error=INVALID_TOKEN renders the friendly sentence and not the raw code.
  • All unit + feature tests pass; Prettier and ESLint clean.

Better Auth redirects magic-link verify failures with a raw code
(INVALID_TOKEN) in the error query param, overwriting the message we
set in errorCallbackURL. Map known codes to human-friendly text at
render time on the login pages.
Better Auth overwrites the error param with its own code, so the
embedded message never reached the user. Keep the /login destination.
@mroderick
mroderick marked this pull request as ready for review August 6, 2026 09:32
@mroderick
mroderick requested a review from till August 6, 2026 09:32
@till

till commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Did we actually have a message before? IMO then code needs to be deleted too somewhere as the claim is "better-auth" is overwriting it.

@mroderick

Copy link
Copy Markdown
Collaborator Author

Did we actually have a message before?

Yes, it was in the url as error query string parameter

@mroderick

Copy link
Copy Markdown
Collaborator Author

IMO then code needs to be deleted too somewhere as the claim is "better-auth" is overwriting it.

It is: https://github.com/codebar/auth/pull/57/changes#diff-65feadee8a853e5eb904f7549f91b174376919a1397a7f9e2aab253c5b2b6100L86

@mroderick
mroderick merged commit 96729e0 into main Aug 6, 2026
7 checks passed
@mroderick
mroderick deleted the fix/friendlier-magic-link-error branch August 6, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants