Skip to content

Commit 1487657

Browse files
Develop-KIMclaude
andauthored
fix(client): XADD/XTRIM with LIMIT 0 must emit the argument (redis#3342)
`XADD ... TRIM.limit` and `XTRIM ... LIMIT` were guarded by a truthy check (`if (options.TRIM.limit)` / `if (options?.LIMIT)`), so an explicit `0` was silently dropped and the server fell back to its implicit default limit. Per the Redis docs, `LIMIT 0` means unlimited trimming, whereas omitting LIMIT caps eviction at `100 * stream-node-max-entries` (10000 by default), so the two are observably different. Against Redis 8.8, trimming a 20000-entry stream with `MAXLEN ~ 1` evicts 10000 entries without LIMIT but 19900 with `LIMIT 0` — meaning a caller asking for unlimited trimming currently gets the capped default instead. Guard on `!== undefined` so `0` is forwarded, matching the recent XGROUP ENTRIESREAD 0 fix (redis#3333). Adds a `LIMIT 0` argument test for both commands. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 264a7ab commit 1487657

4 files changed

Lines changed: 26 additions & 2 deletions

File tree

packages/client/lib/commands/XADD.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,20 @@ describe('XADD', () => {
8080
);
8181
});
8282

83+
it('with TRIM.limit 0', () => {
84+
assert.deepEqual(
85+
parseArgs(XADD, 'key', '*', {
86+
field: 'value'
87+
}, {
88+
TRIM: {
89+
threshold: 1000,
90+
limit: 0
91+
}
92+
}),
93+
['XADD', 'key', '1000', 'LIMIT', '0', '*', 'field', 'value']
94+
);
95+
});
96+
8397
it('with TRIM.policy', () => {
8498
assert.deepEqual(
8599
parseArgs(XADD, 'key', '*', {

packages/client/lib/commands/XADD.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export function parseXAddArguments(
8989

9090
parser.push(options.TRIM.threshold.toString());
9191

92-
if (options.TRIM.limit) {
92+
if (options.TRIM.limit !== undefined) {
9393
parser.push('LIMIT', options.TRIM.limit.toString());
9494
}
9595

packages/client/lib/commands/XTRIM.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ describe('XTRIM', () => {
4343
);
4444
});
4545

46+
it('with LIMIT 0', () => {
47+
assert.deepEqual(
48+
parseArgs(XTRIM, 'key', 'MAXLEN', 1, {
49+
strategyModifier: '~',
50+
LIMIT: 0
51+
}),
52+
['XTRIM', 'key', 'MAXLEN', '~', '1', 'LIMIT', '0']
53+
);
54+
});
55+
4656
it('with strategyModifier, LIMIT', () => {
4757
assert.deepEqual(
4858
parseArgs(XTRIM, 'key', 'MAXLEN', 1, {

packages/client/lib/commands/XTRIM.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export default {
3939

4040
parser.push(threshold.toString());
4141

42-
if (options?.LIMIT) {
42+
if (options?.LIMIT !== undefined) {
4343
parser.push('LIMIT', options.LIMIT.toString());
4444
}
4545

0 commit comments

Comments
 (0)