Files
twenty/packages/twenty-docker
Charles Bochet d4b597e14e fix(docker): run twenty-server in production mode (NODE_ENV=production) (#21635)
## What

Set `ENV NODE_ENV=production` in the `twenty-server` Docker stage
(inherited by `twenty-server-aws` and `twenty`).

## Why — root cause of the empty verification emails

Verification emails have been delivered with an **empty body** in
deployed environments — the subject renders ("Bienvenue chez Twenty :
Veuillez confirmer votre email") but the HTML is `<!DOCTYPE
…><!--$!--><template></template><!--/$-->`, an **errored React Suspense
boundary**. Prod logs showed:

```
TypeError: dispatcher.getOwner is not a function
```

Chain:
1. The prod server stages never set `NODE_ENV`, so at runtime it's
**unset** → React loads its **development** builds.
2. Since the **React 18→19 upgrade** (#21531), React 19's dev JSX
runtime calls `dispatcher.getOwner()` (React 18's did not — which is why
this is a recent regression).
3. That call throws in the server runtime → the email React tree throws
during SSR → `@react-email/render` (which streams without an `onError`)
swallows it into an errored `<Suspense>` boundary → the body ships
empty. The subject is unaffected because it's built without React.

Production React never tracks owner, so `jsx()` never calls `getOwner` —
setting `NODE_ENV=production` removes the failing code path entirely.
It's also simply the correct prod configuration (dev React builds are
slower and emit dev-only behavior).

## Scope / safety

- Only the prod runtime stages are affected. The dev image
(`twenty-app-dev`) keeps its own `NODE_ENV=development`.
- Verified the deployed image currently bakes `NODE_ENV=[]` (unset) and
has a single, matched `react`/`react-dom` 19.2.7 — so this is a mode
issue, not a duplicate-React issue.

## Related
- Mitigation already in place: twentyhq/twenty-infra#729 disables email
verification on prod-eu meanwhile (revert once this ships).
- Diagnostic logging: #21628 (can be reverted after this lands).

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21635?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-16 11:16:09 +02:00
..
2026-01-08 12:45:46 +00:00