EventJournal: after #7461, a custom journal cannot decode EventLog payloads with one union codec
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 55/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- typescript
- Lĩnh vực
- backend
Hướng nghiên cứu
Run the supplied repro with bun repro.ts, then inspect the EventJournal.write and Entry.payload contracts alongside the #7461 changeset. Determine whether the documentation, migration note, or a group decoding helper best makes the per-event payloadSchemaBinary requirement explicit, and confirm the repro no longer leaves custom journals decoding payloads with an incompatible union codec.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
What version of Effect is running?
effect 4.0.0-rc.117 (upgrading from 4.0.0-rc.112)
What steps can reproduce the bug?
A custom EventJournal receives write({ event, primaryKey, payload }) from EventLog and must decode payload itself, for example to validate the entry or to store it in its own format. On rc.112 the payload was MessagePack, which describes itself, so a journal could decode every event in a group with one codec built from the union of the payload schemas.
#7461 removed effect/unstable/encoding/Msgpack. The obvious port, Msgpack.schema(Union) → SchemaBinary.toCodec(Union), compiles and type-checks, but it rejects every payload that EventLog writes. SchemaBinary bytes follow the layout of the codec that wrote them, and EventLog writes each payload with its own event's payloadSchemaBinary, not with a codec for the union.
Minimal repro (both versions installed side by side):
{
"type": "module",
"dependencies": {
"effect-old": "npm:[email protected]",
"effect": "4.0.0-rc.117"
}
}
import * as OldSchema from 'effect-old/Schema'
import * as OldMsgpack from 'effect-old/unstable/encoding/Msgpack'
import * as OldEventGroup from 'effect-old/unstable/eventlog/EventGroup'
import * as Schema from 'effect/Schema'
import * as SchemaBinary from 'effect/unstable/encoding/SchemaBinary'
import * as EventGroup from 'effect/unstable/eventlog/EventGroup'
const oldPayloads = [
OldSchema.Struct({ name: OldSchema.Literal('user/create'), id: OldSchema.String }),
OldSchema.Struct({ name: OldSchema.Literal('user/rename'), id: OldSchema.String, to: OldSchema.String })
] as const
const payloads = [
Schema.Struct({ name: Schema.Literal('user/create'), id: Schema.String }),
Schema.Struct({ name: Schema.Literal('user/rename'), id: Schema.String, to: Schema.String })
] as const
const OldGroup = OldEventGroup.empty
.add({ tag: 'user/create', primaryKey: (p) => p.id, payload: oldPayloads[0] })
.add({ tag: 'user/rename', primaryKey: (p) => p.id, payload: oldPayloads[1] })
const Group = EventGroup.empty
.add({ tag: 'user/create', primaryKey: (p) => p.id, payload: payloads[0] })
.add({ tag: 'user/rename', primaryKey: (p) => p.id, payload: payloads[1] })
const input = { name: 'user/rename', id: 'u1', to: 'Ada' } as const
// rc.112: EventLog writes event.payloadMsgPack bytes; one union codec decodes them.
const oldBytes = OldSchema.encodeSync(OldGroup.events['user/rename'].payloadMsgPack)(input)
console.log('rc.112 union decode:', OldSchema.decodeUnknownSync(OldMsgpack.schema(OldSchema.Union(oldPayloads)))(oldBytes))
// rc.117: EventLog writes event.payloadSchemaBinary bytes; the direct port of the same journal code fails.
const bytes = Schema.encodeSync(Group.events['user/rename'].payloadSchemaBinary)(input)
Schema.decodeUnknownSync(SchemaBinary.toCodec(Schema.Union(payloads)))(bytes)
Run it with bun repro.ts.
What is the expected behavior?
Either a journal can decode an EventLog payload without knowing which event wrote it, as on rc.112, or the API makes the per-event contract hard to miss.
What do you see instead?
rc.112 union decode: { name: "user/rename", id: "u1", to: "Ada" }
SchemaError(Missing key)
The union codec fails for every member of the union, not only for later ones. So every EventLog write through such a journal fails at runtime, and nothing in the types warns about it. The fix is to look up group.events[tag].payloadSchemaBinary for each entry, but nothing in the EventJournal docs or the #7461 changeset points to it.
Additional information
Possible fixes, from smallest to largest:
- Document on
EventJournal.writeandEntry.payloadthat the bytes are encoded with the writing event'spayloadSchemaBinary, so a reader must decode them with that same codec. - Add a migration note to the #7461 changeset:
SchemaBinary.toCodec(schema)is not a drop-in replacement forMsgpack.schema(schema)when the reader's schema differs from the writer's, for example a union reading a member's bytes. - Export a helper that decodes an entry for a group, for example
EventGroup.decodePayload(group, entry), so custom journals do not have to write their own lookup by tag.
- Ngôn ngữ chính
- TypeScript
- Star
- 16.7k
- Fork
- 808
- Merge trung bình
- 10 giờ 17 phút
- Pull request đã merge (30 ngày)
- 850
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của Effect-TS/effect
-
[email protected]: crypto declarations require a global CryptoKey type, breaking Node-only type-checks with @types/node 22 and 24Có thể đã có người làm @effect-bot đã nhận 1 ngày trước. Đang mởbug
Effect-TS/effect#10196 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
OpenApi.fromApi (4.1.0) emits duplicate component schemas with a _1 suffix when the encoded side differsCó thể làm lại được Pull request cho issue này đã bị đóng mà không được merge. Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 1 ngày
-
cluster: a runner that lost its shard lock can still write replies and messages for that shardĐang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 47/100
Maintainer thường phản hồi trong vòng 1 ngày
-
`fromJsonSchemaDocument`: import open `patternProperties`Có thể đã có người làm @effect-bot đã nhận 3 ngày trước. Đang mở
Effect-TS/effect#10048 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của Effect-TS/effect
Issue tương tự
-
Add: Disco Mix SDĐang mởcheck:passed streams:add
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
Maintainer thường phản hồi trong vòng 1 ngày
-
level2 nsoc26
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
GauravKarakoti/SecureFlow#1488 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
deltachat/deltachat-desktop#6914 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
area:cli bug P4
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug from-studio
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
esengine/DeepSeek-Reasonix#14868 ·
Maintainer thường phản hồi trong vòng 1 ngày