Repository navigation
Commit 354dfcd
docs(spec): IEmailService Errors lists name TEMPLATE_INVALID (#26911)
<!-- claude-projects-attribution: {"github_login":"os-support-ai"} -->
_Requested by **Yibo Wang** · [project
thread](https://claude.ai/code/project/chan_01BVUyyPie8gHwoPM18iABwB?thread=cmsg_01BVUyyPie8gHwoPM18iABwBDcxHMZCUNuUDSn6AKJTHtZ)_
Fixes #26803
## 维护者速读
- **改了什么**:`IEmailService` 契约里 `sendTemplate` 和 `renderTemplate` 的错误清单补上
`TEMPLATE_INVALID`,只改注释,不改类型或 schema。
- **为什么改**:插件已经会对含非法占位符的已存模板抛
`TEMPLATE_INVALID`,但契约没写,渠道或应用作者读契约时不知道这是一个永久失败。
- **风险与回滚**:纯文档改动,无运行时影响;回滚即还原这一个提交。
- **先看**:`packages/spec/src/contracts/email-service.ts`(两段新增的 Errors
条目)。
- **两分钟验证**:`git grep -c TEMPLATE_INVALID --
packages/spec/src/contracts/email-service.ts`,预期 4(每个清单两处)。
- **需要你做的**:无,席位落地。
Clause-②: no
Metadata-protocol: none
Skills-docs: no skill lists these codes;
`content/docs/kernel/runtime-services/email-service.mdx` (Typed Error
Codes) updated in this PR; `content/docs/automation/email-templates.mdx`
already names it.
## What changes
- `packages/spec/src/contracts/email-service.ts`: the `sendTemplate` and
`renderTemplate` Errors lists name `TEMPLATE_INVALID`, worded from what
`@objectstack/plugin-email` does: a stored template with 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)
is refused at render with `TEMPLATE_INVALID: email template NAME
(locale=LOCALE): HOLE_AND_RULE`, and is permanent until the template is
re-published.
- `content/docs/kernel/runtime-services/email-service.mdx`: Typed Error
Codes lists `TEMPLATE_INVALID`.
- `.changeset/26803-email-service-template-invalid.md`: patch on
`@objectstack/spec`.
## Why
The runtime throws this code from both methods since #26799, and
`service-messaging` grades it permanent, but the contract a channel or
app author reads did not list it.
## Measured
- `TEMPLATE_INVALID` on `origin/main` 6090bb7: thrown by
`template-engine.ts` render (`TEMPLATE_INVALID: ` + the grammar's
refusal) and re-thrown by `EmailService.resolveAndRenderTemplate` with
the template name and locale in front; both `sendTemplate` and
`renderTemplate` go through that resolver.
- `TEMPLATE_UNSUPPORTED`: `EmailService` never throws it. Only the
`service-messaging` email and inbox channels raise it, when the
registered email service lacks `sendTemplate` / `renderTemplate`. So it
is not added to `IEmailService`'s lists.
- Error-code ledger: does not apply. `error-code-ledger.zod.ts`
registers route `error.code` values; `TEMPLATE_NOT_FOUND`,
`TEMPLATE_INACTIVE` and `MISSING_VARIABLES` are absent from it (0 hits)
because they are `Error` message prefixes, not envelope codes. Mirroring
that, `TEMPLATE_INVALID` is not added, and the ledger and its test are
untouched.
## Acceptance notes
- `content/docs/kernel/runtime-services/email-service.mdx` Typed Error
Codes now lists `TEMPLATE_INVALID` beside the three older codes (claim
surface amended by the seat, 2026-10-27T20:51Z).
## Verification
All on head 6978e58 (spec tests on 0ca6a37; the later commit is .mdx
only).
<details><summary>Spec tests and typecheck (under
os-verify-lock)</summary>
`pnpm --filter @objectstack/spec test && pnpm --filter @objectstack/spec
typecheck`: VERDICT command-exit 0. Test Files 736 passed (736); Tests
22050 passed, 1 todo.
</details>
<details><summary>Derived gates</summary>
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`: On 6978e58: 97 derived, 94 exit 0, 3 NOT
MEASURED with exit 3 (full-build prerequisite: spec
`check:skill-examples`, `check:dual-build-cjs-loads`,
`check:lean-entry-closure`); `--ran`: 94 run, 3 NOT-MEASURED, 0 UNRUN.
Earlier, on 0ca6a37: 73 commands. 71 exit 0.
`check:doc-formula-expressions` first exited 3 (formula not built), then
exit 0 after building formula and lint. `check:dual-build-cjs-loads` and
`check:lean-entry-closure` exit 3 (PREREQUISITE NOT MET, need a full
build): NOT MEASURED locally, CI runs them. `--ran` reconciliation: 73
derived, 71 run, 2 NOT-MEASURED, 0 UNRUN.
</details>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01WGufziYqBAqnKprHc4h25c
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 4049efa commit 354dfcd
3 files changed
Lines changed: 23 additions & 0 deletions
File tree
- .changeset
- content/docs/kernel/runtime-services
- packages/spec/src/contracts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
318 | 318 | | |
319 | 319 | | |
320 | 320 | | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
321 | 327 | | |
322 | 328 | | |
323 | 329 | | |
| |||
337 | 343 | | |
338 | 344 | | |
339 | 345 | | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
340 | 352 | | |
341 | 353 | | |
342 | 354 | | |
| |||
0 commit comments