fix(server): register Lingui message compiler to stop "Uncompiled message detected" log flood (#21416)

## Summary

Fixes #21415.

Server-side `` t`…` `` macro calls (e.g. `FlatEntityMapsException`)
resolve against Lingui's global `i18n` singleton, which `I18nService`
never loads a catalog into and never registers a messages compiler on.
With no `_messageCompiler` set, every such lookup logs `Uncompiled
message detected!` and falls back to the raw string — flooding server
logs (enough to hit hosting log rate limits) and disabling ICU
interpolation on those messages. The warning is emitted unconditionally
by `@lingui/core` (not `NODE_ENV`-gated).

## Changes

Register `compileMessage` via `setMessagesCompiler` in
`I18nService.loadTranslations()`:
- on the global `i18n` singleton (used by the `t` macro), and
- on each per-locale instance.

`@lingui/message-utils` is already a transitive **runtime** dependency
of `@lingui/core` (`@lingui/core@5.1.2 → @lingui/message-utils@^5.1.2`),
so no new dependency is added.

## Testing

Deployed on a real instance: before, the server emitted hundreds of
`Uncompiled message detected` lines/sec (saturating the log rate limit);
after, steady-state shows `0`, and the worker (which shares the code
path) likewise shows `0`. App behaviour is unchanged — messages already
rendered via fallback; this silences the warning and enables ICU on the
affected messages.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
machinagod
2026-06-11 09:05:24 +01:00
committed by GitHub
parent 20c83e1f86
commit 233a6f9fb1
@@ -1,11 +1,13 @@
import { Injectable, type OnModuleInit } from '@nestjs/common';
import {
i18n,
type I18n,
type MessageOptions,
type Messages,
setupI18n,
} from '@lingui/core';
import { compileMessage } from '@lingui/message-utils/compileMessage';
import { type APP_LOCALES, SOURCE_LOCALE } from 'twenty-shared/translations';
import { messages as afMessages } from 'src/engine/core-modules/i18n/locales/generated/af-ZA';
@@ -46,6 +48,10 @@ export class I18nService implements OnModuleInit {
{} as Record<keyof typeof APP_LOCALES, I18n>;
async loadTranslations() {
// The global i18n singleton backs server-side t`…` calls and has no
// compiled catalog, so it needs a runtime message compiler.
i18n.setMessagesCompiler(compileMessage);
const messagesByLocale: Record<keyof typeof APP_LOCALES, Messages> = {
en: enMessages,
'pseudo-en': pseudoEnMessages,
@@ -85,6 +91,7 @@ export class I18nService implements OnModuleInit {
).forEach(([locale, messages]) => {
const localeI18n = setupI18n();
localeI18n.setMessagesCompiler(compileMessage);
localeI18n.load(locale, messages);
localeI18n.activate(locale);