From 5f07976a1f4cf298025707cb5d2ef1d7ef73eefc Mon Sep 17 00:00:00 2001 From: dualfroz Date: Sat, 17 Oct 2026 03:33:29 +0200 Subject: [PATCH] fix: use req.t for the ValidationError message when t is not passed ValidationError only translated its "The following field is invalid" prefix when a t function was passed as the second argument, otherwise it used the English strings. Errors thrown from hooks with just req were always shown in English in the admin toast. The constructor now falls back to req.t when t is not passed, before using the English strings. --- .../src/errors/ValidationError.spec.ts | 22 +++++++++++++++++++ .../payload/src/errors/ValidationError.ts | 6 +++-- 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 packages/payload/src/errors/ValidationError.spec.ts diff --git a/packages/payload/src/errors/ValidationError.spec.ts b/packages/payload/src/errors/ValidationError.spec.ts new file mode 100644 index 0000000..7547089 --- /dev/null +++ b/packages/payload/src/errors/ValidationError.spec.ts @@ -0,0 +1,22 @@ +import { initI18n } from '@payloadcms/translations' +import { de } from '@payloadcms/translations/languages/de' +import { describe, expect, it } from 'vitest' + +import { ValidationError } from './ValidationError.js' + +describe('ValidationError', () => { + it('should translate the message with req.t when no t is passed', async () => { + const i18n = await initI18n({ + config: { fallbackLanguage: 'de', supportedLanguages: { de } }, + context: 'api', + language: 'de', + }) + + const error = new ValidationError({ + errors: [{ message: 'Invalides Passwort', path: 'password' }], + req: { i18n, t: i18n.t }, + }) + + expect(error.message).toBe('Das folgende Feld ist nicht korrekt: password') + }) +}) diff --git a/packages/payload/src/errors/ValidationError.ts b/packages/payload/src/errors/ValidationError.ts index e723028..0c99a10 100644 --- a/packages/payload/src/errors/ValidationError.ts +++ b/packages/payload/src/errors/ValidationError.ts @@ -37,13 +37,15 @@ export class ValidationError extends APIError<{ id?: number | string /** * req needs to be passed through (if you have one) in order to resolve label functions that may be part of the errors array + * and to translate the message when `t` is not passed */ req?: Partial }, t?: TFunction, ) { - const message = t - ? t('error:followingFieldsInvalid', { count: results.errors.length }) + const translate = t ?? results.req?.t + const message = translate + ? translate('error:followingFieldsInvalid', { count: results.errors.length }) : results.errors.length === 1 ? en.translations.error.followingFieldsInvalid_one : en.translations.error.followingFieldsInvalid_other