From 0ca6a372323539d36d904fe6cb8ac83bf87bbcee Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 27 Oct 2026 20:28:06 +0000 Subject: [PATCH 1/2] docs(spec): IEmailService Errors lists name TEMPLATE_INVALID sendTemplate and renderTemplate already refuse a stored template whose hole the authoring rules refuse; the contract now lists that code. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01WGufziYqBAqnKprHc4h25c --- .changeset/26803-email-service-template-invalid.md | 10 ++++++++++ packages/spec/src/contracts/email-service.ts | 12 ++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 .changeset/26803-email-service-template-invalid.md diff --git a/.changeset/26803-email-service-template-invalid.md b/.changeset/26803-email-service-template-invalid.md new file mode 100644 index 00000000000..0632510573a --- /dev/null +++ b/.changeset/26803-email-service-template-invalid.md @@ -0,0 +1,10 @@ +--- +'@objectstack/spec': patch +--- + +docs(spec): `IEmailService.sendTemplate` and `renderTemplate` list `TEMPLATE_INVALID` in their Errors + +Clause-②: no +Metadata-protocol: none + +`@objectstack/plugin-email` already refuses a stored template whose hole the authoring rules refuse (rule `email-template-hole-grammar`), throwing `TEMPLATE_INVALID: email template NAME (locale=LOCALE): HOLE_AND_RULE` from both methods. The contract's Errors lists now name that code beside `TEMPLATE_NOT_FOUND`, `TEMPLATE_INACTIVE` and `MISSING_VARIABLES`, so a channel or app author reading `IEmailService` knows the failure is permanent until the template is re-published. Documentation only: no type or schema changes. diff --git a/packages/spec/src/contracts/email-service.ts b/packages/spec/src/contracts/email-service.ts index e8844a649e5..e7f8098e18c 100644 --- a/packages/spec/src/contracts/email-service.ts +++ b/packages/spec/src/contracts/email-service.ts @@ -318,6 +318,12 @@ export interface IEmailService { * (for a call that named no locale) the name carries no members at all. * - `TEMPLATE_INACTIVE` — the template exists but `active=false`. * - `MISSING_VARIABLES` — declared `required` variables absent from `data`. + * - `TEMPLATE_INVALID` — the stored template has a hole the authoring rules + * refuse (rule `email-template-hole-grammar`: a second formatter, or a + * `currency` argument that is not a literal ISO 4217 code). It is refused + * at render, as `TEMPLATE_INVALID: email template (locale=): + * `, so nothing is delivered. Permanent: retrying cannot + * succeed until the template is re-published without that hole. */ sendTemplate(input: SendTemplateInput): Promise; @@ -337,6 +343,12 @@ export interface IEmailService { * (for a call that named no locale) the name carries no members at all. * - `TEMPLATE_INACTIVE` — the template exists but `active=false`. * - `MISSING_VARIABLES` — declared `required` variables absent from `data`. + * - `TEMPLATE_INVALID` — the stored template has a hole the authoring rules + * refuse (rule `email-template-hole-grammar`: a second formatter, or a + * `currency` argument that is not a literal ISO 4217 code). It is refused + * at render, as `TEMPLATE_INVALID: email template (locale=): + * `, so nothing is rendered. Permanent: retrying cannot + * succeed until the template is re-published without that hole. */ renderTemplate(input: RenderTemplateInput): Promise; From 6978e58122bd4ecc32b7d5aeab155c5a8f3bcbc0 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 27 Oct 2026 20:52:24 +0000 Subject: [PATCH 2/2] docs: email service Typed Error Codes list TEMPLATE_INVALID Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01WGufziYqBAqnKprHc4h25c --- content/docs/kernel/runtime-services/email-service.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/content/docs/kernel/runtime-services/email-service.mdx b/content/docs/kernel/runtime-services/email-service.mdx index a4b97cd1f91..368e8358276 100644 --- a/content/docs/kernel/runtime-services/email-service.mdx +++ b/content/docs/kernel/runtime-services/email-service.mdx @@ -31,3 +31,4 @@ services.email.sendTemplate(input: SendTemplateInput): Promise - `TEMPLATE_NOT_FOUND` - `TEMPLATE_INACTIVE` - `MISSING_VARIABLES` +- `TEMPLATE_INVALID`: the stored template has a hole the authoring rules refuse (a second formatter, or a `currency` argument that is not a literal ISO 4217 code). It is permanent: retrying fails until the template is re-published without that hole. `renderTemplate` raises it too.