You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(cli,plugin-email)!: OS_EMAIL_PROVIDER=resend/postmark with no apiKey fails the boot instead of becoming a LogTransport (#5132) (#5153)
`resolveEmailCapabilityArg` answered a missing API key by rewriting the
provider to `log`, printing a warning, and booting: a server that accepted
every send, recorded each in `sys_email` as sent, and delivered nothing.
#5087 closed that inside plugin-email (`makeTransport` throws rather than
substituting a transport); the CLI kept doing it one layer up, which the
#5087 PR itself flagged in this function's docstring.
It now refuses every mail configuration it cannot deliver through, the way
its neighbouring `smtp` arm already did — resend/postmark with no key, and
a provider tag outside the supported set (retired `sendgrid`/`ses` get the
SMTP migration). Each message names the consequence and both fixes, per
AGENTS.md degradation-log-level. Refusing is only fair because
`OS_EMAIL_PROVIDER=log` is how a deployment says "no mail from here" — a
test pins that it still boots.
The provider vocabulary is read from `@objectstack/plugin-email`
(`isEmailTransportProvider` / `unsupportedProviderFix` from #5094, plus the
new `API_KEY_EMAIL_PROVIDERS` / `emailProviderRequiresApiKey`) rather than
restated in the CLI, and the new constant is tied to `makeTransport` by a
compile error in one direction and a contract test in the other.
Claude-Session: https://claude.ai/code/session_017MCKJaEomEqg4tvz4SzdNd
Co-authored-by: Claude <noreply@anthropic.com>
fix(cli,plugin-email)!: `OS_EMAIL_PROVIDER=resend/postmark` without an API key now fails the boot instead of silently becoming the log transport (#5132)
7
+
8
+
**BREAKING for one configuration: a delivery provider selected without the
9
+
credential it needs.**`os serve` used to answer that by rewriting `provider` to
10
+
`log`, printing a warning, and booting normally. The result was a server that
11
+
accepted every send, recorded each one in `sys_email` as sent, and delivered
12
+
nothing — the warning scrolled past in CI logs and the truth surfaced when a
13
+
user reported never receiving a verification code. #5087 closed exactly this gap
14
+
inside `@objectstack/plugin-email` (`makeTransport` throws rather than
15
+
substituting a transport); the CLI's own capability assembly kept doing it one
16
+
layer up, for `resend` / `postmark`.
17
+
18
+
`resolveEmailCapabilityArg` now refuses every mail configuration it cannot
19
+
deliver through, the way its neighbouring `smtp` arm already did:
20
+
21
+
-`resend` / `postmark` with no `OS_EMAIL_API_KEY` (or `config.email.apiKey`);
22
+
- a `provider` tag outside `log` / `smtp` / `resend` / `postmark` — including
23
+
the retired `sendgrid` / `ses`, which get their SMTP migration in the message.
24
+
25
+
**Who is affected:** deployments (typically CI or preview environments) that set
26
+
`OS_EMAIL_PROVIDER=resend` or `=postmark` without a key and relied on the
27
+
fallback to boot. Nothing else changes — a complete configuration is passed
28
+
through untouched, and an unset `OS_EMAIL_PROVIDER` still defaults to `log`.
29
+
30
+
**Migration — one line, either direction:**
31
+
32
+
- the environment is *not* meant to send mail → `OS_EMAIL_PROVIDER=log`
33
+
(that explicit value is the supported way to say so, and why refusing the
34
+
others is fair);
35
+
- the environment *is* meant to send mail → set `OS_EMAIL_API_KEY` (or
36
+
`config.email.apiKey`).
37
+
38
+
Both errors name the consequence and both fixes, per AGENTS.md's
39
+
degradation-log-level rule.
40
+
41
+
`@objectstack/plugin-email` gains the vocabulary the CLI reads instead of
42
+
restating: `API_KEY_EMAIL_PROVIDERS`, `emailProviderRequiresApiKey()` and the
Copy file name to clipboardExpand all lines: content/docs/deployment/environment-variables.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -124,8 +124,8 @@ Auth settings precedence:
124
124
125
125
| Variable | Type | Default | Description |
126
126
|:---|:---|:---|:---|
127
-
|`OS_EMAIL_PROVIDER`| enum |`log`| Transport. `log`\|`smtp`\|`resend`\|`postmark`. `log` (default) prints to stdout without sending. |
128
-
|`OS_EMAIL_API_KEY`| string | — | API key for `resend` / `postmark`. |
127
+
|`OS_EMAIL_PROVIDER`| enum |`log`| Transport. `log`\|`smtp`\|`resend`\|`postmark`. `log` (default) prints to stdout without sending — it is also how a deployment *declares* that it does not send mail. Any other value is a delivery intent, and a boot that cannot honour it fails loudly instead of substituting the log transport. |
128
+
|`OS_EMAIL_API_KEY`| string | — | API key for `resend` / `postmark`. **Required** when either is selected — a boot without it fails rather than starting with a transport that records every message in `sys_email` as sent and delivers nothing. Set `OS_EMAIL_PROVIDER=log` for environments that should not send mail. |
|`OS_EMAIL_RETRIES`| number |`0`| Retry count for transient send failures (`0` = no retry). |
131
131
|`OS_EMAIL_SMTP_HOST`| string | — | SMTP server hostname. **Required** when `OS_EMAIL_PROVIDER=smtp` — a boot without it fails loudly rather than starting with a transport that logs mail instead of sending it. |
0 commit comments