RPOPLPUSH is not implemented at all — no dispatch arm, no COMMAND INFO entry — even though LMOVE and BRPOPLPUSH both work.
127.0.0.1:7805> RPUSH src a b c
(integer) 3
127.0.0.1:7805> RPOPLPUSH src dst
(error) ERR unknown command 'RPOPLPUSH', with args beginning with:
127.0.0.1:7805> LMOVE src dst RIGHT LEFT
"c"
127.0.0.1:7805> BRPOPLPUSH src dst2 0.1
"b"
127.0.0.1:7805> COMMAND INFO rpoplpush
(empty array)
Real Redis 8.6.1 answers RPOPLPUSH src dst with the popped element.
Why this matters
RPOPLPUSH is deprecated in favour of LMOVE but is not removed, and it is
the form baked into a decade of client code and every reliable-queue tutorial.
redis-py, jedis, go-redis and node-redis all expose it as a first-class
method, so a client calling r.rpoplpush(...) gets an unknown-command error
rather than a working queue.
Where it is half-present
The name is already in the routing/metrics tables, which is what makes the gap
easy to miss:
src/workspace/mod.rs:184 — listed in the command table
src/workspace/mod.rs:281 — comment lists it as a two-key command
src/admin/metrics_setup.rs:540 — has a metrics label for rpoplpush
src/server/conn/blocking.rs:349 — BRPOPLPUSH rewrites itself to
RPOPLPUSH src dst internally
What is missing is the part clients reach: no "RPOPLPUSH" entry in
src/command/metadata.rs and no dispatch arm beside the LMOVE arm at
src/command/mod.rs:366. This is the recurring "registered in some tables,
absent from dispatch" shape.
Scope
RPOPLPUSH source destination ≡ LMOVE source destination RIGHT LEFT —
implement by delegating, not by duplicating the list logic
- add the
metadata.rs entry (arity 3, write, first_key 1, last_key 2, step 1,
ACL LIST|SLOW) so COMMAND INFO/COMMAND DOCS stop lying
- wire all dispatch paths, not just the first one found — this codebase has
more than one and a missing arm is CI-invisible
- consistency + compat-harness entries so the oracle keeps it honest
Provenance
Found while building the RESP2 null-type ground-truth table for #482, by
diffing Moon against a live redis-server 8.6.1 command-for-command. Not a
null-type bug; filed separately so #482 stays a single contract.
RPOPLPUSHis not implemented at all — no dispatch arm, noCOMMAND INFOentry — even thoughLMOVEandBRPOPLPUSHboth work.Real Redis 8.6.1 answers
RPOPLPUSH src dstwith the popped element.Why this matters
RPOPLPUSHis deprecated in favour ofLMOVEbut is not removed, and it isthe form baked into a decade of client code and every reliable-queue tutorial.
redis-py,jedis,go-redisandnode-redisall expose it as a first-classmethod, so a client calling
r.rpoplpush(...)gets an unknown-command errorrather than a working queue.
Where it is half-present
The name is already in the routing/metrics tables, which is what makes the gap
easy to miss:
src/workspace/mod.rs:184— listed in the command tablesrc/workspace/mod.rs:281— comment lists it as a two-key commandsrc/admin/metrics_setup.rs:540— has a metrics label forrpoplpushsrc/server/conn/blocking.rs:349—BRPOPLPUSHrewrites itself toRPOPLPUSH src dstinternallyWhat is missing is the part clients reach: no
"RPOPLPUSH"entry insrc/command/metadata.rsand no dispatch arm beside theLMOVEarm atsrc/command/mod.rs:366. This is the recurring "registered in some tables,absent from dispatch" shape.
Scope
RPOPLPUSH source destination≡LMOVE source destination RIGHT LEFT—implement by delegating, not by duplicating the list logic
metadata.rsentry (arity 3, write, first_key 1, last_key 2, step 1,ACL
LIST|SLOW) soCOMMAND INFO/COMMAND DOCSstop lyingmore than one and a missing arm is CI-invisible
Provenance
Found while building the RESP2 null-type ground-truth table for #482, by
diffing Moon against a live
redis-server 8.6.1command-for-command. Not anull-type bug; filed separately so #482 stays a single contract.