Repository navigation
Conversation
get_messages deserialized every Redis list entry without per-entry error handling, so a single empty string or corrupt JSON entry would raise JSONDecodeError / ValueError and abort the whole read. CosmosHistoryProvider already skips such entries with a warning. Wrap each entry in try/except (ValueError, json.JSONDecodeError), log a warning, and continue, matching the Cosmos behavior.
There was a problem hiding this comment.
🟡 Changes recommended
Valid JSON entries with malformed message shapes can raise uncaught exceptions that abort the entire history read, preventing later valid messages from being returned.
1 open issue
What changed in this PR
This PR makes the Python Redis history provider more resilient by skipping entries that raise JSON decoding or value errors instead of aborting the entire history read.
Changes:
- Add per-entry error handling and warning logs to
get_messages. - Add a regression test confirming valid messages remain readable after empty or invalid JSON entries.
| File | Description |
|---|---|
python/packages/redis/tests/test_providers.py |
Tests recovery from empty and invalid JSON history entries. |
python/packages/redis/agent_framework_redis/_history_provider.py |
Catches deserialization value errors and logs skipped entries. |
Review effort: Balanced
| try: | ||
| messages.append(Message.from_dict(self._deserialize_json(serialized))) | ||
| except (ValueError, json.JSONDecodeError) as exc: | ||
| logger.warning("Skipping malformed Redis history entry: %s", exc) |
Valid JSON that deserializes to a non-dict (null, []) or a dict missing
required fields ({}) previously raised AttributeError/TypeError from
Message.from_dict, which was not caught and aborted the entire read.
Guard the decoded payload with an isinstance-dict check and broaden the
except clause to (ValueError, TypeError, AttributeError, JSONDecodeError).
|
Thanks for the contribution, lisry-1. The code review is clean, but this changes malformed-history handling from fail-fast to skip-and-warn, so the PR needs the required Related Issue answer before approval. Please link an agreed issue with a closing keyword, or document a maintainer-approved exception. Missing AI Assistance alone is not a blocker. |
|
Thanks Eduard van Valkenburg (@eavanvalkenburg). I've opened #9974 to track this bug and linked it in the PR's Related Issue section ( |
|
lisry-1 The new warning logs |
…ormed history Message.from_dict embeds the payload's type value in mismatch errors, so logging str(exc) copies untrusted history data into application logs. Log the exception class name instead and add a regression asserting the sensitive value is absent from the warning.
|
Eduard van Valkenburg (@eavanvalkenburg) thanks for catching that — you're right, I've pushed a fix:
|

Summary
RedisHistoryProvider.get_messagesdeserialized every Redis list entry without per-entry error handling. A single empty string or corrupt JSON entry would raiseJSONDecodeError/ValueErrorand abort the entire read, even when the remaining entries were valid.CosmosHistoryProvider.get_messagesalready handles this case by skipping malformed entries with a warning (see_history_provider.pyinazure-cosmos).Change
Wrap each entry in
try/except (ValueError, json.JSONDecodeError), log a warning, and continue, matching the Cosmos behavior. Added a regression test that feeds["", "not-json", <valid>]and asserts the valid message is still returned.