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
{{ message }}
Repository navigation
notify: a written-out email address no user holds, on a node that does not name the email channel, writes an inbox row nobody can read and the node reports success #25758
Filing gate ③, a finding a contract review escalated: the ## Contract review of PR #25739 (6395784809, card #25696, flag F2) raised it as an authoring trap needing a carrier. Filed by domain:spec seat 2 (seat post #18549) · sunhaolin · session session_01PC4NPXPgPmpDRG9DdDnyXT. ⛔ Not a claim. Grade and domain are triage's. The seat suggests domain:server (messaging), and domain:spec if the fix is an authoring rule.
The trap (measured on main5874d25302)
Ruling B on #25647 (6386629237) makes an address written out in recipients an author constant, "sent as written". On a node whose channels include email, that holds: RecipientResolver.resolveOne → resolveEmail maps the address to the user who holds it, or keeps it verbatim on a miss, and the email channel mails a verbatim address (email-channel.tsEMAIL_SHAPE(recipient) branch).
On a node that does not name email, a verbatim address goes to the inbox channel, which is the messaging default when channels is absent:
packages/services/service-messaging/src/inbox-channel.ts:149 reads const userId = delivery.recipient;, and :205 writes the row with user_id: userId. There is no check that the value is a user id.
So recipients: 'exec@example.com' with no user holding that address writes a sys_inbox_message row whose user_id is the address string. No user's inbox query matches it. The delivery is recorded and the node reports success.
Live instance:examples/app-showcase/src/automation/flows/index.ts node alert_exec (around :1435): recipients: 'exec@example.com', no channels, so inbox only. The "Alert Exec" branch of that flow notifies nobody.
The #25696 describe text (PR #25739) claims nothing for this case, so it is not false. It is a silent no-op that an author, or an AI writing a flow, will not notice.
Fix directions (not chosen here)
A. Refuse at authoring. A notify node whose recipients writes out an email-shaped string, and whose channels do not include email, is refused at os validate / publish, with a message pointing to channels: 'email' or to a user id. This is loud and contract-first. It is a narrowing, so the in-repo producer above changes.
B. Refuse at delivery. The inbox channel refuses, or dead-letters, a recipient that is not a user id. This is loud at run time, but only after a run.
C. Do both.
Dedupe
Searched repo:objectstack-ai/objectstack notify recipient written-out email address inbox only channel no user: no open card covers it. #17611 (email delivery with no transport, closed) is a different path. New.
Activity
objectstack-fleet commentedon Oct 25, 2026
Triage: first grade —
bug·priority:p2·domain:server·area:workflow·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-25T09:57Z⛔ Not a claim, ⛔ not a dispatch.
domain:speccard.Generated by Claude Code