Filing anyway for a second defect that is still unfixed: when a schema mismatch happens, the validator re-raises a jsonschema.ValidationError out of a multiprocessing.Pool worker, that exception cannot be pickled, and the parent reports MaybeEncodingError: ... PicklingError instead of the real error. That is why automated fingerprinting found no signature here, and every future reply-schema mismatch will present the same misleading way.
Details
Occurrence
Run 34545972977, job 103098549810: https://github.com/valkey-io/valkey/actions/runs/34545972977/job/103098549810
Failing step is validator, .github/workflows/daily.yml:2176-2177. The job is defined at daily.yml:2125 with timeout-minutes: 1440, so timeout is not a factor. All three test steps (test, module api test, sentinel tests) passed. The job died in post-processing of the .reqres logs.
The actual error, 650 lines before the ##[error]
JSON schema validation error on /home/runner/work/valkey/valkey/tests/tmp/server.10276.39/stdout.reqres: [0, None, None, None] is not valid under any of the given schemas
argv: ['XPENDING', 'testxadstream', 'testxadgrp1']
Traceback (most recent call last):
File "/home/runner/work/valkey/valkey/./utils/req-res-log-validator.py", line 229, in process_file
jsonschema.validate(instance=res.json, schema=req.schema, cls=schema_validator)
File "/home/runner/.local/lib/python3.12/site-packages/jsonschema/validators.py", line 1121, in validate
raise error
jsonschema.exceptions.ValidationError: [0, None, None, None] is not valid under any of the given schemas
Failed validating 'oneOf' in schema:
...
On instance:
[0, None, None, None]
What the job actually reported at the tail
Traceback (most recent call last):
File "/home/runner/work/valkey/valkey/./utils/req-res-log-validator.py", line 337, in <module>
for result in pool.map(func, paths):
File "/usr/lib/python3.12/multiprocessing/pool.py", line 367, in map
return self._map_async(func, iterable, mapstar, chunksize).get()
File "/usr/lib/python3.12/multiprocessing/pool.py", line 774, in get
raise self._value
multiprocessing.pool.MaybeEncodingError: Error sending result: '<multiprocessing.pool.ExceptionWithTraceback object at 0x7f0275781010>'. Reason: 'PicklingError("Can't pickle <function <lambda> at 0x7f0276898b80>: attribute lookup <lambda> on jsonschema._types failed")'
##[error]Process completed with exit code 1.
utils/req-res-log-validator.py:230-239 catches the ValidationError, prints diagnostics, then re-raises it inside a pool worker. jsonschema.ValidationError holds a reference to a TypeChecker lambda in jsonschema._types, which is unpicklable, so the parent never sees the real exception. Suggested fix at line 239: sys.exit(1), or raise a plain RuntimeError(str(err)), instead of re-raising the jsonschema exception. This is still present at upstream/unstable.
Why the reply is valid
src/t_stream.c:3064-3072:
if (justinfo) {
addReplyArrayLen(c, 4);
/* Total number of messages in the PEL. */
addReplyLongLong(c, raxSize(group->pel));
/* First and last IDs. */
if (raxSize(group->pel) == 0) {
addReplyNull(c); /* Start. */
addReplyNull(c); /* End. */
addReplyNullArray(c); /* Clients. */
The pre-fix src/commands/xpending.json had a two-branch oneOf, extended form and summary form, and the summary branch declared items[1]/items[2] as type: string with pattern: [0-9]+-[0-9]+ and items[3] as type: array. Nothing accepted nulls.
Why only 1 of 7 Daily runs
Deterministic, in a narrow window, not intermittent.
d46565268 "Implement XACKDEL and XDELEX command (#4629)", 2026-09-10, added the first tests under --log-req-res that call XPENDING <key> <group> on an empty PEL, at tests/unit/type/stream.tcl:777 and :799:
assert_equal {} [lindex [r XPENDING testxadstream testxadgrp1] 1]
98f915212 "Fix XPENDING reply schema for empty pending lists (#4653)", 2026-09-11 00:01 -0700, added a third oneOf branch for the empty summary.
The failing run's head commit is 95e0e9ac7 (2026-09-10 13:32 -0700) and the run was created 2026-09-11T00:19Z. git merge-base --is-ancestor 98f915212 95e0e9ac7 confirms the fix is not in that tree: the Daily started 18 minutes after the fix merged but built a commit from before it. The other six Daily runs fall outside the window, either before #4629 or after #4653.
Ruled out
Timeout (1440 minutes, job ran to completion). Test failure (no [err] or [exception]; all runtest steps passed). Dependency drift (jsonschema==4.17.3 pinned in utils/req-res-validator/requirements.txt, installed cleanly). Build failure (make SERVER_CFLAGS='-Werror -DLOG_REQ_RES' succeeded). Runner or network flake.
Upstream
valkey-io/valkey#4653 fixes the root cause and I agree with its diagnosis and its added oneOf branch; its description already names #4629 as the trigger. No upstream issue covers the validator's error masking.
This was generated by AI but verified, with love, by a human.
The
reply-schemas-validatorjob failed once in the Daily runs because theXPENDING <key> <group>reply schema insrc/commands/xpending.jsondid not describe the reply the server actually sends when the consumer group's pending entries list is empty.src/t_stream.c:3069-3072returns[0, nil, nil, nil], but the schema required elements 1 and 2 to be ID strings and element 3 to be an array, soutils/req-res-log-validator.pyrejected a valid reply and exited 1. The root cause is already fixed upstream by valkey-io/valkey#4653, and the failing run just predates it by 18 minutes.Filing anyway for a second defect that is still unfixed: when a schema mismatch happens, the validator re-raises a
jsonschema.ValidationErrorout of amultiprocessing.Poolworker, that exception cannot be pickled, and the parent reportsMaybeEncodingError: ... PicklingErrorinstead of the real error. That is why automated fingerprinting found no signature here, and every future reply-schema mismatch will present the same misleading way.Details
Occurrence
Run 34545972977, job 103098549810: https://github.com/valkey-io/valkey/actions/runs/34545972977/job/103098549810
Failing step is
validator,.github/workflows/daily.yml:2176-2177. The job is defined atdaily.yml:2125withtimeout-minutes: 1440, so timeout is not a factor. All three test steps (test,module api test,sentinel tests) passed. The job died in post-processing of the.reqreslogs.The actual error, 650 lines before the
##[error]What the job actually reported at the tail
utils/req-res-log-validator.py:230-239catches theValidationError, prints diagnostics, then re-raises it inside a pool worker.jsonschema.ValidationErrorholds a reference to aTypeCheckerlambda injsonschema._types, which is unpicklable, so the parent never sees the real exception. Suggested fix at line 239:sys.exit(1), or raise a plainRuntimeError(str(err)), instead of re-raising thejsonschemaexception. This is still present atupstream/unstable.Why the reply is valid
src/t_stream.c:3064-3072:The pre-fix
src/commands/xpending.jsonhad a two-branchoneOf, extended form and summary form, and the summary branch declareditems[1]/items[2]astype: stringwithpattern: [0-9]+-[0-9]+anditems[3]astype: array. Nothing accepted nulls.Why only 1 of 7 Daily runs
Deterministic, in a narrow window, not intermittent.
d46565268"Implement XACKDEL and XDELEX command (#4629)", 2026-09-10, added the first tests under--log-req-resthat callXPENDING <key> <group>on an empty PEL, attests/unit/type/stream.tcl:777and:799:assert_equal {} [lindex [r XPENDING testxadstream testxadgrp1] 1]98f915212"Fix XPENDING reply schema for empty pending lists (#4653)", 2026-09-11 00:01 -0700, added a thirdoneOfbranch for the empty summary.The failing run's head commit is
95e0e9ac7(2026-09-10 13:32 -0700) and the run was created 2026-09-11T00:19Z.git merge-base --is-ancestor 98f915212 95e0e9ac7confirms the fix is not in that tree: the Daily started 18 minutes after the fix merged but built a commit from before it. The other six Daily runs fall outside the window, either before #4629 or after #4653.Ruled out
Timeout (1440 minutes, job ran to completion). Test failure (no
[err]or[exception]; all runtest steps passed). Dependency drift (jsonschema==4.17.3pinned inutils/req-res-validator/requirements.txt, installed cleanly). Build failure (make SERVER_CFLAGS='-Werror -DLOG_REQ_RES'succeeded). Runner or network flake.Upstream
valkey-io/valkey#4653 fixes the root cause and I agree with its diagnosis and its added
oneOfbranch; its description already names #4629 as the trigger. No upstream issue covers the validator's error masking.This was generated by AI but verified, with love, by a human.