Skip to content

RESP3: XREAD/XREADGROUP reply should be a Map (stream-name => entries), not an Array #577

Description

@TinDang97

Gap

Redis 7+ types a non-empty XREAD/XREADGROUP reply as a RESP3 Map keyed by stream name (%N stream => entries). Moon emits the RESP2 Array shape (*N [name, entries]) in every protocol — there is no Frame::Map construction anywhere in src/command/stream/ (stream_read.rs / stream_write.rs build Frame::Array unconditionally).

Impact

A RESP3 client that dispatches on the reply container type (expecting a Map) is served the wrong shape. Systemic across the whole XREAD/XREADGROUP family, not specific to any one mode. The null-array miss case is unaffected (a null array is identical in both protocols).

Discovered by

The client-compat probe parity_xreadgroup_history_resp3_reply_is_map (added in #564, batch #527/#526/#469/#520/#521). It is currently waived in scripts/client-compat/manifest.yaml with owner resp3-type-fidelity; the waiver ratchets — test-client-compat.sh --strict will FAIL the moment Moon starts answering a Map, so this issue cannot silently rot.

Fix sketch

In the XREAD/XREADGROUP reply builders, when the connection negotiated RESP3 (HELLO 3), wrap the per-stream results in Frame::Map keyed by stream name instead of the array-of-pairs. Mirror the resp3-type-fidelity conversion approach already used for other reply types (src/protocol/resp3.rs). Add a resp3 unit test and flip the manifest waiver to a clean pass.

Owner milestone: resp3-type-fidelity.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions