Found while implementing #12178 (PR: #12447). Filed unassigned, not fixed there — these live in other lanes' packages and in hand-written docs, and #12178's scope was packages/spec/src/automation/io-node-config.zod.ts only.
What #12178 settled
notify's template path does not resolve a per-recipient locale, and deliberately does not. Per the maintainer ruling of 2026-08-13, a per-user locale is deferred until measured pull, so "recipient locale" resolves to the deployment default — II18nService.getDefaultLocale() — or to payload.locale, which is interpolated once, before fan-out and is therefore one value for the whole notification. sys_user carries no locale column, so there is no per-recipient source to read even if a channel wanted one.
#12178 corrected all five sites in the spec file. The same promise is still made in four places it did not cover.
The remaining sites
1. packages/services/service-automation/src/builtin/notify-node.ts L197 — the worst of the four. This is the node descriptor's configSchema field description, i.e. text rendered in the Studio form an author fills in:
description: 'Email template name (sys_email_template.name) — resolved by (name, recipient locale) at delivery time and rendered per recipient. Mutually exclusive with inline title/message.',
Same sentence spec just retired, on the surface with the shortest path to an authoring mistake.
2. content/docs/automation/email-templates.mdx L164-166 — hand-written docs, and the only site that states the false conclusion outright rather than merely licensing it:
- `template` names the bundle. The delivery path resolves
`(name, recipient locale)` **per recipient, at delivery time**, so one node
mails each person in their own language.
"one node mails each person in their own language" is not something the delivery path does.
3. packages/services/service-messaging/src/messaging-service-plugin.ts L250 — the log line named in #12178's body:
ctx.logger.info('[messaging] email channel registered (renders sys_notification_template; notify `template` refs resolve sys_email_template per recipient locale)');
Note the path: #12178 and its triage both call this service-messaging/src/plugin.ts, which does not exist in the tree. The file is messaging-service-plugin.ts.
4. packages/services/service-automation/src/builtin/notify-node.ts L288 — an internal comment ("resolved per recipient locale at delivery"). Lowest stakes; listed for a consistent sweep. A sibling comment at notify-node.test.ts L232 says the same and would move with it.
Why it is worth a card rather than a shrug
#12178 recorded the cost of believing this wording: converting notify nodes on the belief that non-English recipients get non-English mail is a net regression — TEMPLATE_* failures classify permanent and dead-letter, and the inbox channel starts requiring an email service with renderTemplate() where inline text needed none. Sites 1 and 2 are the two an app author is most likely to read, so leaving them is close to leaving the defect in place while the spec file reads correctly.
Suggested fix
Text only, no behaviour change, mirroring the honest wording already in service-messaging/src/email-channel.ts L86-99 and now in the spec file: name the resolved value as payload.locale or the deployment default, say it is one locale per notification rather than per recipient, and date the 2026-08-13 deferral so it reads as a decision with provenance. Sites 1 and 2 are the ones that matter; 3 and 4 are cheap to carry along.
Two lanes if they should be split: domain:services owns 1, 3, 4; the docs page (2) is content/docs/automation/.
Generated by Claude Code
Found while implementing #12178 (PR: #12447). Filed unassigned, not fixed there — these live in other lanes' packages and in hand-written docs, and #12178's scope was
packages/spec/src/automation/io-node-config.zod.tsonly.What #12178 settled
notify'stemplatepath does not resolve a per-recipient locale, and deliberately does not. Per the maintainer ruling of 2026-08-13, a per-user locale is deferred until measured pull, so "recipient locale" resolves to the deployment default —II18nService.getDefaultLocale()— or topayload.locale, which is interpolated once, before fan-out and is therefore one value for the whole notification.sys_usercarries no locale column, so there is no per-recipient source to read even if a channel wanted one.#12178 corrected all five sites in the spec file. The same promise is still made in four places it did not cover.
The remaining sites
1.
packages/services/service-automation/src/builtin/notify-node.tsL197 — the worst of the four. This is the node descriptor'sconfigSchemafield description, i.e. text rendered in the Studio form an author fills in:Same sentence spec just retired, on the surface with the shortest path to an authoring mistake.
2.
content/docs/automation/email-templates.mdxL164-166 — hand-written docs, and the only site that states the false conclusion outright rather than merely licensing it:"one node mails each person in their own language" is not something the delivery path does.
3.
packages/services/service-messaging/src/messaging-service-plugin.tsL250 — the log line named in #12178's body:Note the path: #12178 and its triage both call this
service-messaging/src/plugin.ts, which does not exist in the tree. The file ismessaging-service-plugin.ts.4.
packages/services/service-automation/src/builtin/notify-node.tsL288 — an internal comment ("resolved per recipient locale at delivery"). Lowest stakes; listed for a consistent sweep. A sibling comment atnotify-node.test.tsL232 says the same and would move with it.Why it is worth a card rather than a shrug
#12178 recorded the cost of believing this wording: converting
notifynodes on the belief that non-English recipients get non-English mail is a net regression —TEMPLATE_*failures classifypermanentand dead-letter, and the inbox channel starts requiring an email service withrenderTemplate()where inline text needed none. Sites 1 and 2 are the two an app author is most likely to read, so leaving them is close to leaving the defect in place while the spec file reads correctly.Suggested fix
Text only, no behaviour change, mirroring the honest wording already in
service-messaging/src/email-channel.tsL86-99 and now in the spec file: name the resolved value aspayload.localeor the deployment default, say it is one locale per notification rather than per recipient, and date the 2026-08-13 deferral so it reads as a decision with provenance. Sites 1 and 2 are the ones that matter; 3 and 4 are cheap to carry along.Two lanes if they should be split:
domain:servicesowns 1, 3, 4; the docs page (2) iscontent/docs/automation/.Generated by Claude Code