From 42e844ab9f349b766ad3330247524c77ffbf1f9c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Mar 2026 15:19:33 +0000 Subject: [PATCH 1/2] Initial plan From a957d3f11c0a4d61167e4d573e6d58ceb6e6c8d8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Mar 2026 15:28:43 +0000 Subject: [PATCH 2/2] Fix hexlify log format and add regression test docstring for PreparedQueryNotFound Co-authored-by: mykaul <4655593+mykaul@users.noreply.github.com> --- cassandra/cluster.py | 9 +++++++-- tests/unit/test_response_future.py | 8 +++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/cassandra/cluster.py b/cassandra/cluster.py index 9de850442f..a7b3ed802b 100644 --- a/cassandra/cluster.py +++ b/cassandra/cluster.py @@ -4724,13 +4724,18 @@ def _set_result(self, host, connection, pool, response): self.prepared_statement = self.session.cluster._prepared_statements[query_id] except KeyError: if not self.prepared_statement: - log.error("Tried to execute unknown prepared statement: id=%s", hexlify(query_id)) + log.error( + "Tried to execute unknown prepared statement: id=%s", + hexlify(query_id).decode('ascii'), + ) self._set_final_exception(response) return log.warning( "UNPREPARED for query id %s while executing statement id %s. " "Could not resolve returned id in cache, proceeding with in-flight context.", - hexlify(query_id), hexlify(self.prepared_statement.query_id)) + hexlify(query_id).decode('ascii'), + hexlify(self.prepared_statement.query_id).decode('ascii'), + ) current_keyspace = self._connection.keyspace prepared_keyspace = self.prepared_statement.keyspace diff --git a/tests/unit/test_response_future.py b/tests/unit/test_response_future.py index 679a0ad4fe..9c6c3e235c 100644 --- a/tests/unit/test_response_future.py +++ b/tests/unit/test_response_future.py @@ -622,6 +622,12 @@ def test_prepared_query_not_found_bad_keyspace(self): rf.result() def test_prepared_query_not_found_uses_local_prepared_context(self): + """ + Regression test: the original code asserted response.info == self.prepared_statement.query_id, + which raised AssertionError when the server returned a different query id (e.g. due to a + coordinator race or restart), preventing recovery. The fix removes the assertion and falls + back to the in-flight prepared_statement context so reprepare can still proceed. + """ session = self.make_session() pool = session._pools.get.return_value connection = Mock(spec=Connection) @@ -639,7 +645,7 @@ def test_prepared_query_not_found_uses_local_prepared_context(self): rf.prepared_statement.query_string = "SELECT * FROM foobar" rf.prepared_statement.keyspace = "FooKeyspace" - # Different query id in UNPREPARED response should not prevent reprepare when local context exists. + # Server returns a *different* query id in UNPREPARED — old code would raise AssertionError here. result = Mock(spec=PreparedQueryNotFound, info=b"other-query-id") rf._set_result(None, None, None, result)