Skip to content

fix(client): send an empty message in PING - #3464

Open
xia-chao wants to merge 1 commit into
redis:masterfrom
xia-chao:fix/ping-empty
Open

xia-chao wants to merge 1 commit into
redis:masterfrom
xia-chao:fix/ping-empty

Conversation

@xia-chao

@xia-chao xia-chao commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Closes #3463

ping('') went out as a bare PING. The guard was if (message), and '' is falsy, so the message was never pushed onto the wire and the server answered PONG instead of "".

await client.ping('');   // before: "PONG"   after: ""
await client.ping();     // still "PONG" - the omitted form is unchanged

Change

   parseCommand(parser: CommandParser, message?: RedisArgument) {
     parser.push('PING');
-    if (message) {
+    if (message !== undefined) {
       parser.push(message);
     }
   },

An empty message is not an omitted message - '' is a valid RedisArgument and Redis accepts PING '', which is why the raw sendCommand(['PING', '']) path always worked. The sibling ECHO never had this guard, and XREAD/SINTERCARD already compare against undefined for the same reason.

Tests

packages/client/lib/commands/PING.spec.ts:

  • parseArgs(PING, '') now asserts ['PING', ''].
  • The ping integration test additionally asserts that await client.ping('') returns ''. It runs on both the server and cluster topologies through testUtils.testAll.

Verification

  • npm run build
  • npx mocha -r tsx './lib/RESP/**/*.spec.ts' - 133 passing
  • npm test -w @redis/client - 3079 passing, 4 pending, 2 failing; both failures are Socket socketTimeout timeouts in socket.spec.ts, unrelated to this change (details below)
  • npm run lint - clean
The 2 failing tests

Both are mocha 2000ms timeouts in Socket › socketTimeout:

1) Socket
     socketTimeout
       should timeout with positive socketTimeout values:
   Error: Timeout of 2000ms exceeded.
2) Socket
     socketTimeout
       should not timeout with undefined socketTimeout:
   Error: Timeout of 2000ms exceeded.

They are load-dependent and not caused by this change. The full suite was run twice - once with this change and once on a clean origin/master - and the same two tests fail identically in both:

tree passing failing
clean origin/master 3078 2 (Socket socketTimeout x2)
this branch 3079 2 (the same two)

The only difference is the +1 from the new with an empty message unit test. Running socket.spec.ts on its own passes on both trees, so they only time out under the load of the full parallel suite. This change touches PING.ts only and nothing on the socket path.


Checklist

  • Does npm test pass with this change (including linting)?
  • Is the new or changed code fully tested?
  • Is a documentation update included (if this change modifies existing APIs, or introduces new ones)?

No documentation change: ping(message?: RedisArgument) is unchanged, and the fix makes the implementation match what the signature already promised.


Note

Low Risk
Narrow client command-encoding fix with added tests; no auth, security, or data-path changes.

Overview
Fixes ping('') so it sends PING '' and returns an empty string instead of behaving like a bare PING (PONG).

The PING command parser now treats an empty string as an explicit message by checking message !== undefined rather than truthiness, so '' is pushed on the wire while omitting the argument still sends only PING.

Tests cover parseArgs for '' and integration client.ping('') on open server and cluster setups.

Reviewed by Cursor Bugbot for commit 7741511. Bugbot is set up for automated code reviews on this repo. Configure here.

ping('') was sent as a bare PING because the guard used truthiness: '' is falsy, so the message was never pushed onto the wire and the server answered PONG instead of an empty string.

Compare against undefined instead, the same way XREAD and SINTERCARD already do.
@xia-chao

Copy link
Copy Markdown
Contributor Author

@nkaradzhov
Please review

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ping('') is sent as a bare PING - the empty message is silently dropped

1 participant