langgenius / langgenius/dify

Signup email validation message ignores the app language

Open Beginner friendly
#39,011 2 comments 1 reaction 0 assignees View on GitHub
1.16.0 project#dify
Dominant language
TypeScript
Stars
156k
Forks
24.6k
Avg merge
22h 9m
Merged PRs (30d)
610

Description

### Self Checks

- [X] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
- [X] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general).
- [X] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
- [X] I confirm that I am using English to submit this report, otherwise it will be closed.
- [X] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
- [X] Please do not modify this template :) and fill in all the required fields.

### Dify version

1.16.0-rc1 (read from `main` @ `120c38ba`)

### Cloud or Self Hosted

Self Hosted (Source)

### Steps to reproduce

Client-side only, so it applies to Cloud too.

1. Set the browser's language to something other than the app's — e.g. app 简体中文, browser German.
2. Go to `/signup`.
3. Type `abc` into the email field and press "Verify".

### ✔️ Expected Behavior

The invalid-email message in the app's language: 请输入有效的邮箱地址.

That string already exists — `error.emailInValid` in `web/i18n//login.json`, translated in all 23 locales.

### ❌ Actual Behavior

The browser's own message, in the **browser's** language, ignoring the app's:

| browser | shown today |
| --- | --- |
| de | Die E-Mail-Adresse muss ein @-Zeichen enthalten. In der Angabe "abc" fehlt ein @-Zeichen. |
| ja | メール アドレスに「@」を挿入してください。「abc」内に「@」がありません。 |
| fr | Veuillez inclure "@" dans l'adresse e-mail. Il manque un symbole "@" dans "abc". |

`web/app/signup/components/input-mail.tsx` has `` inside a `` with no `noValidate`, so the browser runs constraint validation before `submit` fires. For a value the browser rejects, `handleSubmit` never runs — and `handleSubmit` is where the translated messages live:

```ts
if (!email) {
toast.error(t(($) => $['error.emailEmpty'], { ns: 'login' }))
return
}
if (!emailRegex.test(email)) {
toast.error(t(($) => $['error.emailInValid'], { ns: 'login' }))
return
}
```

Which message you get depends on *how* the email is wrong, because `emailRegex` and the browser disagree:

- `abc` — browser rejects → browser's language, `handleSubmit` never runs
- `a@b` — browser accepts, `emailRegex` rejects → 请输入有效的邮箱地址

So `error.emailInValid` is unreachable for the most common typo there is, and reachable only for a rarer one. The submit button is `disabled={isPending || !email}`, so the empty case can't be reached from the UI and `error.emailEmpty` never shows either.

#### Where it came from

This looks like a side effect of #30455 / #30456 (`refactor(web): align signup mail submit and tests`, merged 2026-01-04), which moved this form from `onSubmit={noop}` + button `onClick` to a real `` with `type="submit"`. That's the right call for form semantics — but submitting a form for real also runs the browser's constraint validation first, and `type="email"` now intercepts submit before `handleSubmit` can report the translated message.

The code matches: the forms that were not refactored — `(shareLayout)/webapp-signin/*` and `webapp-reset-password`, still `onSubmit={noop}` with no submit button — never trigger native validation and are unaffected. Only the refactored signup form is.

`input-mail.spec.tsx` (added by that same PR) can't catch it either: it drives the form with `fireEvent.submit(form)`, which dispatches the event directly and skips constraint validation entirely. The tests pass precisely because they bypass the path that breaks in a browser.

#### Suggested fix

Add `noValidate` to the form. The app already validates both cases and already has both messages translated, so this just lets them fire:

```diff
{
e.preventDefault()
handleSubmit()
}}
>
```

`type="email"` stays, so the mobile email keyboard is unaffected — `noValidate` only turns off constraint validation. No new strings and nothing for translators.

A regression test belongs in the existing `input-mail.spec.tsx`, but it has to drive the form the way a browser does — `fireEvent.submit` won't reproduce this. Asserting on `input.checkValidity()` / `validity.valid` covers it without needing a real browser.

Happy to open the PR if you'd like to assign this to me.

Contributor guide

Open the contributing guide

Research direction

Start with web/app/signup/components/input-mail.tsx and the existing input-mail.spec.tsx test. Check how native form validation affects submission for an invalid email; the issue notes that fireEvent.submit bypasses this behavior and suggests checking input.checkValidity() or validity.valid. Done when an invalid email produces the app-language message and the regression test covers the browser validation path.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend, internationalization
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.