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.

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions