Skip to content

[backport] Backport sweep for 9.1 - #5074

Open
valkeyrie-ops[bot] wants to merge 23 commits into
9.1from
agent/backport/sweep/9.1
Open

valkeyrie-ops[bot] wants to merge 23 commits into
9.1from
agent/backport/sweep/9.1

Conversation

@valkeyrie-ops

@valkeyrie-ops valkeyrie-ops Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Backport sweep for 9.1

Automated cherry-picks from PRs marked "To be backported".

Applied

Source PR Title Detail
#4968 Fix crash when a database's keyspace is replaced mid-stage during defrag conflicts resolved by Claude Code
#4863 Fix module blocking of RESP3 Pub/Sub clients
#4775 Bound the time spent evicting keys from the tracking table
#4190 Reclaim dead client IDs from the tracking table (#4143) conflicts resolved by Claude Code
#3683 cmake: Fix missing release_header dependency for cli, benchmark, and gtest
#4995 Fix GEOSEARCH repeated BYPOLYGON memory leak conflicts resolved by Claude Code
#5046 Fix memory leak in GetCommandKeysWithFlags
#5092 Count expired but unreaped hash fields in objectComputeSize conflicts resolved by Claude Code
#5091 Fix VM_Call crash on script-mode validation errors
#5133 Keep sds lengths in size_t when comparing and caching keys
#5210 Mark sorted-set increments and weights as doubles
#5128 Propagate PFADD elements applied before an INVALIDOBJ error
#5191 Clear stale cross-slot flag before computing a command's slot
#5127 Script debugger: reset *argc on partial-read exit to fix server crash in SYNC mode
#5211 Remove key specs from hash NUMFIELDS arguments conflicts resolved by Claude Code
#5213 Represent valid expiry condition combinations in command metadata
#5118 Read Lua error table fields without invoking metamethods
#5159 Fill unmatched postponed reply lengths left by a module
#3510 Fix TLS infinite busy loop when write/read handlers are removed
#4091 Fix crash when processing heartbeat from a node with no local role
#4351 Fix NULL deref in usUntilEarliestTimer when all time events are deleted
#4171 Fix ping_sent getting stuck when peer traffic keeps link alive

AI resolution details are posted as comments on this PR when available.

Needs attention

These candidates could not be applied automatically and need a maintainer to follow up.

1 candidate(s)
Source PR Title Outcome Reason
#4954 Match listpack for lex range commands on mixed-score btree zsets skipped-conflict target branch lacks conflicted file(s): src/ordered_index.c

Generated by valkey-ci-agent using Claude Code.

taham0 and others added 2 commits October 28, 2026 09:12
…rag (#4968)

Clear `defrag_later` (and reset its cursor) at the start of every DbKeys defrag stage

Signed-off-by: Muhammad Taha <76549451+taham0@users.noreply.github.com>
Backport-Source-PR: 4968
moduleBlockClient() treated every subscribed client as unblockable because getClientType() returns CLIENT_TYPE_PUBSUB. A RESP3 client can still run commands while subscribed, so ValkeyModule_BlockClient and ValkeyModule_BlockClientOnAuth returned NULL with ENOTSUP and queued no reply. Allow blocking those clients again, matching the processCommand rule that only RESP2 Pub/Sub clients are restricted. Keyspace notifications still cannot block them.

Introduced by PR 1819 (8.1.1). Restores the pre-8.1.1 behavior for RESP3 subscribed clients; no change for RESP2 clients or keyspace-notification contexts.

Fixes #4862

---------

Signed-off-by: quanyeyang <quanyemostima@gmail.com>
Signed-off-by: Rain Valentine <rsg000@gmail.com>
Co-authored-by: Rain Valentine <rsg000@gmail.com>
Co-authored-by: Roshan Khatri <117414976+roshkhatri@users.noreply.github.com>
Backport-Source-PR: 4863
@valkeyrie-ops valkeyrie-ops Bot added ai-resolved-conflicts AI is used to resolve conflicts in automated backport PRs. backport Backport PR opened by valkey-ci-agent labels Oct 28, 2026
@valkeyrie-ops

valkeyrie-ops Bot commented Oct 28, 2026

Copy link
Copy Markdown
Author

AI backport resolution: source PR #4968

Fix crash when a database's keyspace is replaced mid-stage during defrag

1 AI-edited file

Claude Summary

The conflict is resolved and verified. Here's a summary of what I did:

Conflict resolution in tests/unit/moduleapi/defrag.tcl: The conflict arose because the upstream unstable branch has two extra tests ("global defrag resumes via cursor" and "global defrag is revisited on later cycles") that were added by a different PR not present on the 9.1 branch. The cherry-picked hunk carried them as context. I kept only what PR #4968 actually added — the new Module defrag: FLUSHDB ASYNC while a deferred key is defragged test — and dropped the two unrelated tests. Dropping them is required for correctness, not just minimalism: they assert on defragtest_global_resumes/defragtest_global_wrong_cursor stats that the 9.1 version of tests/modules/defragtest.c doesn't export (its FragInfo only reports datatype_*, global_attempts, and global_defragged).

Verification of the auto-merged files (no edits needed):

  • src/defrag.c: the fix clears defrag_later and resets defrag_later_cursor at the start of each DbKeys stage (src/defrag.c:941-943). Both symbols exist on this branch, and the deferral path the fix protects (defragLater via moduleDefragValue) is present.
  • tests/modules/defragtest.c: the new frag.stall command and stall logic in FragDefrag merged cleanly; all module APIs it uses (ValkeyModule_WrongArity, ValkeyModule_StringToLongLong, ValkeyModule_ReplyWithError, ValkeyModule_ReplyWithSimpleString) exist in this branch's valkeymodule.h.
  • Tcl helpers used by the new test (wait_for_condition, getInfoProperty, s) and the active_defrag_key_hits/active_defrag_key_misses info fields all exist on 9.1.

Checks passed: no conflict markers remain in any of the three files; both C files pass gcc -fsyntax-only; the final diff is 66 insertions across 3 files, exactly matching the upstream PR's stat. I did not stage or commit, per instructions.

AI-edited files requiring review

  • tests/unit/moduleapi/defrag.tcl — view diff

Full backport commit diff: commit b779efc567fe.

Please review these AI resolutions for correctness before merging.

@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3aab1feb-5d0b-4a88-9786-27827e042bd5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@codecov

codecov Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.06337% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.39%. Comparing base (29173b6) to head (22d6207).

Files with missing lines Patch % Lines
src/module.c 12.50% 14 Missing ⚠️
src/tracking.c 96.96% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              9.1    #5074      +/-   ##
==========================================
+ Coverage   76.98%   77.39%   +0.40%     
==========================================
  Files         165      166       +1     
  Lines       82092    82730     +638     
==========================================
+ Hits        63201    64029     +828     
+ Misses      18891    18701     -190     
Files with missing lines Coverage Δ
src/ae.c 82.42% <100.00%> (+0.06%) ⬆️
src/cluster.c 92.71% <100.00%> (+0.24%) ⬆️
src/cluster_legacy.c 88.67% <100.00%> (+0.30%) ⬆️
src/commands.def 100.00% <ø> (ø)
src/debug.c 55.59% <100.00%> (+0.19%) ⬆️
src/defrag.c 82.14% <100.00%> (+1.35%) ⬆️
src/evict.c 99.15% <100.00%> (ø)
src/geo.c 93.92% <100.00%> (-0.40%) ⬇️
src/hyperloglog.c 92.89% <100.00%> (+0.23%) ⬆️
src/object.c 91.38% <100.00%> (-0.59%) ⬇️
... and 7 more

... and 12 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@valkeyrie-ops

valkeyrie-ops Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Author

Automatic follow-up for the current backport head.

I did not push a fix: This is a flaky, allocator/heap-state-dependent failure, not a deterministic breakage attributable to the backport: it failed only in one of 30+ jobs, including passing in the identical clang variant of the same sanitizer job. No default-branch candidate commit touches tests/unit/hashexpire.tcl or the hash TTL/RESTORE memory path, so there is nothing to port, and the only 'author' option would be to weaken or remove the memory-equality assertion the test exists to verify, which is prohibited.

Looked at the failure from this run.

tanmayBeginsJourney and others added 2 commits October 29, 2026 09:06
Limits time evicting from tracking table.

Signed-off-by: Tanmay <tanmaymohan12@gmail.com>
Backport-Source-PR: 4775
Dead client sweeper and active defrag support.

Signed-off-by: Ray Lei <rayjinghaolei@gmail.com>
Backport-Source-PR: 4190
@valkeyrie-ops

valkeyrie-ops Bot commented Oct 29, 2026

Copy link
Copy Markdown
Author

AI backport resolution: source PR #4190

Reclaim dead client IDs from the tracking table (#4143)

1 AI-edited file

Claude Summary

The merge conflict is resolved and verified. The resulting diff is exactly 1,388 added lines, matching the upstream PR's 1,388 insertions.

The conflict: src/debug.c had a single conflict in the DEBUG HELP text array inside debugCommand(). The incoming side carried two blocks: the PR's new SWEEP-TRACKING-TABLE help entry plus a SET-DISABLE-DENY-SCRIPTS help block that was merely surrounding context on the source branch. I verified the 9.1 branch's help array has no SET-DISABLE-DENY-SCRIPTS entry (only the command handler exists, at src/debug.c:1016), so I kept only the three SWEEP-TRACKING-TABLE help lines the PR actually added. That makes the debug.c change +6 lines (help text plus the sweep-tracking-table handler calling trackingSweepFull()), identical to the upstream diff.

Verification of the auto-merged files: I confirmed every symbol the new code depends on already exists on the 9.1 branch — lookupClientByID, activeDefragAlloc, the rax API (raxSetData, raxTryInsert, etc.), doneStatus/DEFRAG_DONE in defrag.c, the server.clients_index / stat_active_defrag_* / tracking_clients fields, getMonotonicUs as a swappable function pointer (which the unit tests rely on), and the Tcl helpers (perform_defrag_test, client_reply_off_wait_for_server, valkey_deferring_client, assert_morethan, clean_all). The staged tracking.c, server.c, server.h, and defrag.c changes are purely additive and byte-for-byte match the source PR's hunks.

Build check: the four touched C files compile and the full valkey-server binary links cleanly. No conflict markers remain in any of the eight touched files (a repo-wide marker grep only hits pre-existing unrelated files like READMEs where ======= is a markdown underline). Per your instructions I did not run git add or git commit, so debug.c still shows as unmerged in git status — the resolution is complete in the working tree and ready for git cherry-pick --continue.

AI-edited files requiring review

Full backport commit diff: commit c619f8eb1361.

Please review these AI resolutions for correctness before merging.

@valkeyrie-ops

valkeyrie-ops Bot commented Oct 29, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-sanitizer-address (gcc) (run) stopped with an error: The CI-fix attempt failed: ci-fix-agent cannot reach /home/runner/work/valkey-ci-agent/valkey-ci-agent: /home/runner is not traversable.

1 similar comment
@valkeyrie-ops

valkeyrie-ops Bot commented Oct 29, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-sanitizer-address (gcc) (run) stopped with an error: The CI-fix attempt failed: ci-fix-agent cannot reach /home/runner/work/valkey-ci-agent/valkey-ci-agent: /home/runner is not traversable.

poiuj and others added 2 commits October 30, 2026 09:06
…gtest (#3683)

release.c is compiled into valkey-cli, valkey-benchmark, and the
valkeylib-gtest static library, but only valkey-server declared a
dependency on the release_header custom target that runs mkreleasehdr.sh
to generate src/release.h. On a clean build (no stale release.h on disk)
or under high parallelism, those targets could attempt to compile
release.c before the header was generated and fail with "release.h: No
such file or directory".

Add the missing add_dependencies(... release_header) for all three.

Signed-off-by: Vadym Khoptynets <1099644+poiuj@users.noreply.github.com>
Backport-Source-PR: 3683
Repeated `BYPOLYGON` options in `GEOSEARCH` and `GEOSEARCHSTORE`
overwrite the previous vertex array without freeing it. Only the final
array is released, leaking memory even when the source key does not
exist.

Free the previous vertices before allocating a replacement, preserving
the existing behavior of using the last polygon. Add
regression tests for both commands, invalid `COUNT` cleanup, and
retained memory across repeated requests.

is merged first, I'll rebase this PR and use the new name.

  Validation:
  - GEO suite: 75 passed.
- New tests with 4 I/O threads and `io-threads-always-active yes`: 2
passed.
- The leak regression fails against the parent commit and passes with
this fix.

Signed-off-by: DaeMyung Kang <charsyam@gmail.com>
Backport-Source-PR: 4995
@valkeyrie-ops

valkeyrie-ops Bot commented Oct 30, 2026

Copy link
Copy Markdown
Author

AI backport resolution: source PR #4995

Fix GEOSEARCH repeated BYPOLYGON memory leak

1 AI-edited file

Claude Summary

Both files are resolved and verified. Here's a summary:

Resolution summary

src/geo.c had one conflict, in the documentation comment block directly above georadiusGeneric() (lines 528–534). The target branch's 9.1 comment for GEOSEARCH didn't yet mention BYPOLYGON (though the GEOSEARCHSTORE line below it already did, and the bypolygon parsing code exists on the branch). I took the PR's side, which adds the [BYPOLYGON numvertices longitude latitude ...] syntax line for GEOSEARCH and fixes the pre-existing WITHASH → WITHHASH typo — matching the upstream diff exactly.

The actual leak fix — a geoPolygonPointsFree(&amp;shape); call inserted before the vertex array is re-allocated in the bypolygon option branch (src/geo.c:679) — had already merged cleanly and is in place. It frees any vertices from a previous BYPOLYGON occurrence before the replacement zmalloc, preserving last-polygon-wins behavior.

tests/unit/geo.tcl auto-merged with the two regression tests ("repeated BYPOLYGON uses the last polygon" and "repeated BYPOLYGON releases previous vertices"). I verified the helpers they rely on exist on this branch: assert_lessthan and assert_error in tests/support/test.tcl, the test proc's 4-arg form supporting the external:skip tag, and geoPolygonPointsFree() (the pre-rename name this branch uses) in src/geo.c:91.

Verification: no conflict markers remain in either file, gcc -fsyntax-only passes on geo.c, and the resulting diff matches the upstream PR's size (+7/-2 in geo.c, +30 in geo.tcl). Per instructions I did not run git add or git commit, so the cherry-pick is ready for git cherry-pick --continue.

AI-edited files requiring review

Full backport commit diff: commit 1b7c5ccda267.

Please review these AI resolutions for correctness before merging.

@valkeyrie-ops

valkeyrie-ops Bot commented Oct 30, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-almalinux8-jemalloc (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41063016947).

@valkeyrie-ops

valkeyrie-ops Bot commented Oct 30, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-almalinux8-jemalloc (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41071507137).

@valkeyrie-ops

valkeyrie-ops Bot commented Oct 30, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-alpine-libc-malloc (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41080191566).

christopherlim98 and others added 2 commits October 31, 2026 09:04
For large key lists, `ValkeyModule_GetCommandKeysWithFlags` allocates
temporary storage in `getKeysResult` and returns without freeing it.
This adds the missing cleanup after copying the positions and flags into
the returned arrays.

Fixes #5042

Signed-off-by: Christopher Lim <41635847+christopherlim98@users.noreply.github.com>
Backport-Source-PR: 5046
`objectComputeSize()` samples a hashtable-encoded hash with a validating
iterator, which skips fields whose TTL has passed but that have not been
reaped yet. Those fields still occupy memory, and `hashtableSize()`,
which the sampled average is multiplied by, still counts them. The
result is under-reported whenever expired fields are larger than live
ones.

**Example:** one small live field plus 99 expired 1 KB fields, with
active expiry disabled. `MEMORY USAGE` reports ~4 KB for a hash that
holds ~100 KB.

**Fix:** iterate with `HASHTABLE_ITER_SKIP_VALIDATION`. This matches the
rest of `objectComputeSize()`, where the listpack branch uses
`zmalloc_size()` and sets and sorted sets have no validator, and it
matches `rdbSaveObject()`, which already skips validation when walking
the hash. It also removes a dependency on expiry evaluation, which reads
server state a size estimate should not need.

Once expired fields are reaped the reported value is unchanged. Existing
`hashexpire.tcl` tests that check memory drops after expiry wait for
reaping first, so they are unaffected.

Adds a regression test to `tests/unit/hashexpire.tcl`.

Signed-off-by: Sushil Paneru <sushil.paneru1@gmail.com>
Backport-Source-PR: 5092
@valkeyrie-ops

valkeyrie-ops Bot commented Oct 31, 2026

Copy link
Copy Markdown
Author

AI backport resolution: source PR #5092

Count expired but unreaped hash fields in objectComputeSize

1 AI-edited file

Claude Summary

Resolution complete. Here's a summary of what was done:

Conflict resolution: tests/unit/hashexpire.tcl

The single conflict was inside the large start_server {tags {"hashexpire"}} block, between the "Hash Encoding Transitions with TTL - Create New Fields with TTL" test and the "HGETALL skips expired fields" test. The incoming side carried three things:

  1. The new "MEMORY USAGE counts expired but unreaped hash fields" test — this is the actual content of PR Count expired but unreaped hash fields in objectComputeSize #5092.
  2. An "HMGET batch lookup skips expired hash fields" test plus hash-max-listpack-entries config set/restore lines — these are context from a different commit (Optimize HMGET, SMISMEMBER and ZMSCORE with batched hashtable lookup #4017, "Optimize HMGET... batched hashtable lookup", first tagged in 9.2.0-rc1) that doesn't exist on the 9.1 branch, which is what caused the conflict.

I kept only the new MEMORY USAGE test (matching the upstream PR's exact diff) and dropped the 9.2-only surrounding context. The test works on 9.1 without the hash-max-listpack-entries 0 wrapper because its 1000-byte values exceed hash-max-listpack-value (default 64) and hpexpire is used, both of which force hashtable encoding — so the test's assert_encoding hashtable assertion holds.

Verification

  • No conflict markers remain (grep confirms).
  • src/object.c (auto-merged) compiles: the hashtableInitIterator(&amp;iter, ht, HASHTABLE_ITER_SKIP_VALIDATION) call matches the 9.1 signature (uint8_t flags parameter) and the macro exists in src/hashtable.h:103; gcc -fsyntax-only passes.
  • Test helpers used (assert_morethan, assert_encoding) exist in tests/support/test.tcl, and MEMORY USAGE ... SAMPLES 0 (sample everything) is supported on 9.1 (src/object.c:1780).
  • The Tcl file parses as structurally complete (info complete = 1).
  • Final diff is 36 insertions / 1 deletion across the two files — identical in size to the upstream commit.

No files other than the two listed were modified, and nothing was staged or committed.

AI-edited files requiring review

Full backport commit diff: commit 2a9680219c6f.

Please review these AI resolutions for correctness before merging.

@valkeyrie-ops

valkeyrie-ops Bot commented Oct 31, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-fedorarawhide-jemalloc (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41209807626).

@valkeyrie-ops

valkeyrie-ops Bot commented Oct 31, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-fedorarawhide-jemalloc (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41214466193).

@valkeyrie-ops

valkeyrie-ops Bot commented Oct 31, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-sanitizer-address (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41219364439).

dvkashapov and others added 2 commits November 1, 2026 09:05
Calling `ValkeyModule_Call` with `S` but without `E` crashes on
validation errors because cleanup calls `sdslen()` on a NULL error
message. Use a generic ERR message for error accounting when no reply
message was requested.

---------

Signed-off-by: Daniil Kashapov <daniil.kashapov.ykt@gmail.com>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
Backport-Source-PR: 5091
dictSdsKeyCompare() and evictionPoolPopulate() stored sdslen() in an
int. At 2^31 bytes that is negative. dictSdsKeyCompare() then passes a
sign-extended length to memcmp(), which reads past the end of both
strings and can report two equal strings as different, so a set or hash
stores the same member twice, or crash. evictionPoolPopulate() takes the
short-key branch and memcpy()s a huge length into the 255 byte cached
sds, crashing the server.

dictSdsKeyCompare() became the comparator for every data hashtable in
fb655db (#3366), replacing hashtableSdsKeyCompare(), which compared
size_t lengths. The eviction pool narrowing is older.

Signed-off-by: Madelyn Olson <madelyneolson@gmail.com>
Backport-Source-PR: 5133
@valkeyrie-ops

valkeyrie-ops Bot commented Nov 1, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-ubuntu-libc-malloc (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41310897186).

@valkeyrie-ops

valkeyrie-ops Bot commented Nov 1, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-ubuntu-libc-malloc (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41315820969).

@valkeyrie-ops

valkeyrie-ops Bot commented Nov 1, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-ubuntu-tls (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41320817793).

sarthakaggarwal97 and others added 2 commits November 2, 2026 09:06
The command metadata describes several sorted-set numeric arguments as
integers even though the command implementations accept floating-point
values:

- The `ZINCRBY` increment.
- `ZINTER` and `ZINTERSTORE` weights.
- `ZUNION` and `ZUNIONSTORE` weights.

This prevents metadata consumers from accurately representing valid
command arguments.

Credits to @madolson for finding this issue.

Signed-off-by: Sarthak Aggarwal <sarthagg@amazon.com>
Backport-Source-PR: 5210
PFADD with several elements applies them to the HLL in place, one at a
time. On a malformed sparse HLL, an early element can modify the key and
a later one can then fail with INVALIDOBJ. When that happened, PFADD
returned before `signalModifiedKey()`, the keyspace event and the
`server.dirty` update. The modified value stayed on the primary and
never reached replicas or the AOF, and it did not trip WATCH or client
tracking. This change finishes the bookkeeping for the elements that
were applied, and propagates a PFADD that carries only those elements.

Signed-off-by: Madelyn Olson <madelyneolson@gmail.com>
Backport-Source-PR: 5128
@valkeyrie-ops

valkeyrie-ops Bot commented Nov 2, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-almalinux9-tls-module-no-tls (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41452559364).

@valkeyrie-ops

valkeyrie-ops Bot commented Nov 2, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-almalinux9-tls-module-no-tls (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41461567606).

@valkeyrie-ops

valkeyrie-ops Bot commented Nov 2, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

No fix for clang-format-check (run). The reported failure was not reproduced by code: no code-owned reproduction command could be established. No edit was attempted.

@valkeyrie-ops

valkeyrie-ops Bot commented Nov 2, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-sanitizer-undefined (gcc) (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41481017821).

In cluster mode, one script that calls a cross-slot command (for example
`MGET` on keys in two slots) makes every later `server.call()` from any
script or function fail with "Attempted to access a non local key in a
cluster node" until the server restarts. That includes keyless commands
like `PING`. `clusterSlotByCommand()` only ORs `READ_FLAGS_CROSSSLOT`
into the flags it is given, and the pooled client that
`ValkeyModule_Call()` uses never resets them between calls. The bit
stays set, and `getNodeByQuery()` rejects everything sent through that
client. The fix clears both result flags at the start of
`clusterSlotByCommand()`.

Signed-off-by: Madelyn Olson <madelyneolson@gmail.com>
Backport-Source-PR: 5191
… in SYNC mode (#5127)

`readReadCommandInternal()` in `src/scripting_engine.c` asserts `*argc
== 0` on entry (`scripting_engine.c:749`). When a SCRIPT DEBUG SYNC
command spans more than one read, the function parses the `*<n>\r\n`
header, writes `*argc = n`, and then exits through `keep_reading`
because the rest of the command has not arrived yet. The caller
(`scriptingEngineDebuggerProcessCommands()`) reads at most 1024 bytes
per `connRead()` call, appends to `ds.cbuf`, and retries — but `argc`
still holds `n` from the first call, so the assert fires on the second.
In SYNC mode the assert runs in the server process, which exits with
SIGABRT. Any debugger command longer than 1024 bytes triggers this; TCP
framing can split shorter commands too.

Signed-off-by: Madelyn Olson <madelyneolson@gmail.com>
Backport-Source-PR: 5127
@valkeyrie-ops

valkeyrie-ops Bot commented Nov 3, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-centosstream9-jemalloc (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41643802266).

@valkeyrie-ops

valkeyrie-ops Bot commented Nov 3, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

The fix attempt for test-centosstream9-jemalloc (run) stopped with an error: The CI-fix attempt failed: the fix job ended without a result (see https://github.com/valkey-io/valkey-ci-agent/actions/runs/41653168623).

@valkeyrie-ops

valkeyrie-ops Bot commented Nov 3, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

No fix for test-sanitizer-force-defrag (run). The reported failure was not reproduced by code: no code-owned reproduction command could be established. No edit was attempted.

What the bot checked

The `numfields` argument in several hash-field commands incorrectly has
`key_spec_index: 0`.

`numfields` is a count, not a key. Associating it with a key
specification produces incorrect command introspection data and can
mislead clients that consume the command metadata.

Credits to @madolson for finding this issue.

Signed-off-by: Sarthak Aggarwal <sarthagg@amazon.com>
Backport-Source-PR: 5211
)

The command metadata currently places `NX`, `XX`, `GT`, and `LT` in a
flat `oneof`.

That incorrectly describes all four options as mutually exclusive. While
`NX` is exclusive, `XX` can validly be combined with either `GT` or
`LT`.

The inaccurate structure affects `COMMAND DOCS` and clients generated
from the command metadata.

Signed-off-by: Sarthak Aggarwal <sarthagg@amazon.com>
Backport-Source-PR: 5213
@valkeyrie-ops

valkeyrie-ops Bot commented Nov 4, 2026

Copy link
Copy Markdown
Author

AI backport resolution: source PR #5211

Remove key specs from hash NUMFIELDS arguments

1 AI-edited file

Claude Summary

The conflict is resolved and verified. Here's a summary:

The conflict: The cherry-pick's only conflict was in tests/unit/introspection-2.tcl, inside the start_server {tags {"introspection"}} block. The incoming side contained two tests: the new COMMAND DOCS does not mark hash field counts as keys test that PR #5211 actually added, plus a pre-existing upstream test (COMMAND GETKEYS* NOT_KEY commands should report no key arguments) that was only surrounding diff context and doesn't exist on the 9.1 branch.

The resolution: I kept only the new COMMAND DOCS test — the one the PR added — placed after the COMMAND GETKEYSANDFLAGS MSETEX test and before COMMAND LIST syntax error, matching upstream's placement. I dropped the NOT_KEY test since it was never on 9.1 and isn't part of this PR's intent. The auto-merged files (src/commands.def and the 11 hash command JSON files) correctly remove key_spec_index from the numfields argument and needed no adaptation.

Verification:

  • No conflict markers remain, and the file parses as complete Tcl.
  • The full working-tree diff is 24 insertions / 22 deletions across 13 files — identical in shape to the upstream commit.
  • The server builds cleanly, and ./runtest --single unit/introspection-2 passes all 53 tests, including the new one.

I did not stage or commit anything, per your instructions — the cherry-pick is ready for git add and git cherry-pick --continue.

AI-edited files requiring review

  • tests/unit/introspection-2.tcl — view diff

Full backport commit diff: commit 4a5544688451.

Please review these AI resolutions for correctness before merging.

@valkeyrie-ops

valkeyrie-ops Bot commented Nov 4, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

No fix for test-ubuntu-libc-malloc (run). The reported failure was not reproduced by code: every reproduction probe passed without reproducing the failure. No edit was attempted.

What the bot checked

@valkeyrie-ops

valkeyrie-ops Bot commented Nov 4, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

No fix for test-sanitizer-undefined (gcc) (run). The reported failure was not reproduced by code: every reproduction probe passed without reproducing the failure. No edit was attempted.

What the bot checked

A script that returns or raises an error table whose metatable has a
raising `__index` makes the server exit with `PANIC: unprotected error
in call to Lua API`. `luaExtractErrorInformation()` reads the table's
fields with `lua_getfield()`, which runs `__index`, and it does so after
the script's `lua_pcall()` has returned, so the error has nowhere to
unwind to. This switches those four reads to `lua_rawget()`, the same
fix redis/redis#11032 applied to `luaReplyToServerReply()`. Every Valkey
release is affected.

Signed-off-by: Madelyn Olson <madelyneolson@gmail.com>
Backport-Source-PR: 5118
A module that calls `ValkeyModule_ReplyWithArray(ctx,
VALKEYMODULE_POSTPONED_LEN)` (or Map, Set, Attribute) and never sets the
length crashes the server with SIGSEGV. `moduleFreeContext()` already
detects this and logs an API misuse warning, but it leaves the NULL
placeholder node in the reply list, and the write path dereferences it.
The fix fills each leftover placeholder with an empty array header, the
same call `ValkeyModule_ReplySetArrayLength()` makes. For a thread safe
context on a blocked client, this happens on the main thread when the
client is unblocked, since the context may only be freed later.

Signed-off-by: Madelyn Olson <madelyneolson@gmail.com>
Backport-Source-PR: 5159
@valkeyrie-ops

valkeyrie-ops Bot commented Nov 5, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

No fix for test-sanitizer-undefined (gcc) (run). The reported failure was not reproduced by code: every reproduction probe passed without reproducing the failure. No edit was attempted.

What the bot checked

yairgott and others added 2 commits November 6, 2026 09:05
…4091)

When loading nodes.conf, if a replica entry references a primary that
has no separate entry in the file, the primary is implicitly created
with flags=0 (noflags).
```
/* Get primary if any. Set the primary and populate primary's
 * replica list. */
if (argv[3][0] != '-') {
    ...
    primary = clusterLookupNode(argv[3], sdslen(argv[3]));
    if (!primary) {
        primary = createClusterNode(argv[3], 0);
        clusterAddNode(primary);
    }
```

Once created this way, the node's role can never be recovered: the
role-switch logic only triggers transitions between known roles
(replica->primary or primary->replica), so a noflags node is stuck
indefinitely. This leads to:

- serverAssert(nodeIsPrimary(sender)) crash when the noflags node
  claims to be a primary and the slot-update path is reached.
  It should have been working correctly before #2337, because we
  always call `clusterSetNodeAsPrimary`.

- Inconsistent local view where a replica has replicaof set but no
  REPLICA flag, breaking failover candidate selection and CLUSTER
  NODES output.

This also happens when a noflags entry is directly present in nodes.conf
(e.g. manual edit or corruption). The node role will not be able to
recover correctly from noflags.

Fix by adding fallback branches: if the sender has no role locally,
adopt its advertised role (primary or replica) on the first heartbeat.

Signed-off-by: Binbin <binloveplay1314@qq.com>
Backport-Source-PR: 4091
@valkeyrie-ops

valkeyrie-ops Bot commented Nov 6, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

No fix for test-ubuntu-libc-malloc (run). The reported failure was not reproduced by code: every reproduction probe passed without reproducing the failure. No edit was attempted.

What the bot checked

The test introduced by fbfe087 asserts '*Connection refused*' in
valkey-cli stderr, but on macOS hiredis reports the connection failure
to the shut-down node as 'setsockopt(TCP_NODELAY): Invalid argument', so
the assertion fails on macOS runners. Additionally, the test's final
wait asserted cluster_known_nodes == 1 on nodes 0 and 1, which depends
on the preceding 'Delete reachable node' test having removed node 1 and
therefore fails when the test is run in isolation with --only.

Both failures are test bugs, not server misbehavior: an OS-dependent
error string and an inter-test state dependency. The fix keeps all the
meaningful assertions (command reports success, CLUSTER RESET warning is
printed, a connect error occurred, and the node is actually forgotten by
every live cluster member via the existing cluster_get_node_by_id helper
inside wait_for_condition), so nothing the test guarantees is weakened,
and it uses polling helpers already defined on this branch. No merged
upstream commit fixes this assertion, so a minimal test-only patch is
appropriate for the release branch.
@valkeyrie-ops

valkeyrie-ops Bot commented Nov 6, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

Pushed 4523761d1a55 to this branch with a fix for test-macos-latest (run).

What failed: del-node: Delete unreachable node without slots in tests/unit/cluster/cli.tcl (test-macos-latest)

Root cause: The test introduced by fbfe087 asserts 'Connection refused' in valkey-cli stderr, but on macOS hiredis reports the connection failure to the shut-down node as 'setsockopt(TCP_NODELAY): Invalid argument', so the assertion fails on macOS runners. Additionally, the test's final wait asserted cluster_known_nodes == 1 on nodes 0 and 1, which depends on the preceding 'Delete reachable node' test having removed node 1 and therefore fails when the test is run in isolation with --only.

The fix: Both failures are test bugs, not server misbehavior: an OS-dependent error string and an inter-test state dependency. The fix keeps all the meaningful assertions (command reports success, CLUSTER RESET warning is printed, a connect error occurred, and the node is actually forgotten by every live cluster member via the existing cluster_get_node_by_id helper inside wait_for_condition), so nothing the test guarantees is weakened, and it uses polling helpers already defined on this branch. No merged upstream commit fixes this assertion, so a minimal test-only patch is appropriate for the release branch.

What the bot checked

  • Existing fixes found: 3c46f667bcc9 Fix valkey-cli --cluster del-node for unreachable nodes (Fix valkey-cli --cluster del-node for unreachable nodes #3209) (already ported as fbfe087); 9c4c8739da2e Apply the library load timeout to FUNCTION RESTORE (Apply the library load timeout to FUNCTION RESTORE #5181) (port candidate); cc45d0637a00 Fix various typos around otherwise with a comma (port candidate); 42aff62b3094 Fix "setup" related typos (port candidate); eefa8927dc2b fix: Reject corrupt stream RDB with shared NACK across consumers (Reject corrupt stream RDB with shared NACK across consumers (CVE-2026-63639) #4073) (already ported as 509cb3c)

  • Reproduced on every run (failed on both of two runs):

    make -j"$(nproc)" SERVER_CFLAGS='-Werror' USE_LIBBACKTRACE=yes && ./runtest --verbose --clients 1 --no-latency --dump-logs --single unit/cluster/cli --only 'del-node: Delete unreachable node without slots' --fastfail --loops 1 --timeout 600
  • With the fix, the reproduction passed 10 loops:

    make -j"$(nproc)" SERVER_CFLAGS='-Werror' USE_LIBBACKTRACE=yes && ./runtest --verbose --clients 1 --no-latency --dump-logs --single unit/cluster/cli --only 'del-node: Delete unreachable node without slots' --fastfail --loops 10 --timeout 600
  • Review: The log shows the failure is an assertion on an OS-dependent errno string from the vendored client library, and the patch replaces it with the stable valkey-cli message while keeping the exit-code, warning, and success assertions intact. The final-state change swaps an order-dependent known-nodes count for a polled, targeted check that the deleted node was forgotten, fixing the --only isolation failure named in the diagnosis without any skip or fixed sleep.

  • Accepted on attempt 2 of 3.

The agent's own notes

The previous iteration already proved the relaxed connect-error match works on macOS (the run got past the assertion and failed only at the cluster-state wait). The new final check passes trivially in isolation because valkey-cli sends CLUSTER FORGET to all reachable nodes before printing OK, and in a full-file run node 1 is standalone after CLUSTER RESET SOFT and never re-learns the deleted ID thanks to the forget blacklist.

This PR's own CI decides whether the fix holds, and the bot never merges.

@valkeyrie-ops

valkeyrie-ops Bot commented Nov 6, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

No fix for test-ubuntu-32bit (run). The reported failure was not reproduced by code: every reproduction probe passed without reproducing the failure. No edit was attempted.

What the bot checked

  • Did not reproduce (the build passed):

    make -j"$(nproc)" 32bit SERVER_CFLAGS='-Werror' USE_LIBBACKTRACE=yes GTEST_CFLAGS="-I/usr/src/googletest/googletest/include -I/usr/src/googletest/googlemock/include" GTEST_LIBS="/usr/lib32/libgtest.a /usr/lib32/libgmock.a"

    No test failed: the reproduction is the job's own build, and its compiler output is the failure.

@valkeyrie-ops

valkeyrie-ops Bot commented Nov 6, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

No fix for test-sanitizer-undefined (clang) (run). The reported failure was not reproduced by code: every reproduction probe passed without reproducing the failure. No edit was attempted.

What the bot checked

royenheart and others added 2 commits November 7, 2026 09:04
…ed (#4351)

Fixes #4349

When every time event in an event loop is pending deletion
(`id == AE_DELETED_EVENT_ID`, a "zombie-only" list), the rescan in
`usUntilEarliestTimer()` finds no valid timer, `earliest` stays `NULL`,
and the function dereferences it.

The empty-list case is guarded; the all-zombies case is not. The state
is reachable whenever the last timer of a loop fires `AE_NOMORE` (marked
deleted in `processTimeEvents`, reaped only on the next pass) or is deleted
between `processTimeEvents` runs, while the lookup runs before the reaping on
every iteration. Redis fixed the identical bug in redis/redis#15391; this
applies the same guard.

Signed-off-by: Haoze Xie <royenheart@outlook.com>
Signed-off-by: Yuan Tan <yuantan098@gmail.com>
Backport-Source-PR: 4351
The broken-link detection in clusterCron only reconnects a link when
no traffic is seen for more than half the node timeout (data_delay >
cluster_node_timeout/2).

This leaves ping_sent unable to advance in this case: while ping_sent
is set we never send another PING (clusterCron skips nodes with an
outstanding ping), and ping_sent is only cleared by a PONG. If the peer
keeps the link alive with its own PINGs (refreshing the data_received)
while our outgoing PING was lost, the link is never reconnected, so
ping_sent stays set forever and we can not send PING.

Force a reconnect when our PING has been outstanding for a full node
timeout without a PONG, independent of data_received. The reconnect
itself
sends a fresh PING, letting us receive a PONG and clear the stale state.

A practical example is a two-node cluster: with no third node to confirm
or correct the failure, a lost PING combined with the peer's own PINGs
leaves the node permanently stuck in PFAIL state.

Signed-off-by: Binbin <binloveplay1314@qq.com>
Backport-Source-PR: 4171
@valkeyrie-ops

valkeyrie-ops Bot commented Nov 7, 2026

Copy link
Copy Markdown
Author

Automatic follow-up on this backport's CI.

No fix for test-sanitizer-address (run). The reported failure was not reproduced by code: every reproduction probe passed without reproducing the failure. No edit was attempted.

What the bot checked

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

Labels

ai-resolved-conflicts AI is used to resolve conflicts in automated backport PRs. backport Backport PR opened by valkey-ci-agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.