Skip to content

fix(core): SendContext.meta is write-only — nothing hands it back to the caller #108

Description

@productdevbook

What happens

SendContext.meta is documented as "a shared mutable bag for middleware to leave notes in", and docs/architecture.md shows a middleware writing ctx.meta.durationMs. Nothing ever hands that context back to the caller, so whatever a middleware writes there is unreachable.

Reproduction

const email = createEmail({ driver: mock(), defaults, use: [
  defineMiddleware("timing", (next) => async (msgs, ctx) => {
    const r = await next(msgs, ctx)
    ctx.meta.durationMs = 42
    return r
  }),
]})
const result = await email.send(msg)

Observed:

Result keys: ["data","error"]
data keys:   ["id","driver","at"]
is ctx.meta reachable from the return value? NO — the bag is write-only

Why it matters

The documented use for meta — passing observability data out of the pipeline — cannot be done. A middleware can only get information out by closing over its own variable, which breaks as soon as two sends run concurrently, because the closure has no way to tell them apart. So the feature reads as supported and is not.

Where

src/core/types.ts:281 documents it; src/core/email.ts:225-232 creates the context and discards it; docs/architecture.md demonstrates the unreachable pattern.

Suggested fix

Either surface it — carry the per-send meta onto EmailResult (and onto EmailError, so a failure can be traced too) — or drop meta from the public type and rewrite the docs example. Surfacing it is the smaller change and the one the docs already promise.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions