Skip to content

_set_keyspace_for_all_pools callback receives only the last pool's errors instead of all accumulated errors #914

Description

@mykaul

Bug

Session._set_keyspace_for_all_pools() passes host_errors (the last pool to finish) instead of errors (the accumulated dict of all pools) to its callback.

cassandra/cluster.py:3442 — present since the original commit d281b50c9 (2013-10-11).

def pool_finished_setting_keyspace(pool, host_errors):
    remaining_callbacks.remove(pool)
    if host_errors:
        errors[pool.host] = host_errors          # accumulates into `errors`

    if not remaining_callbacks:
        callback(host_errors)                     # BUG: should be callback(errors)

Impact

When the last pool to finish has no errors, the callback receives [] (empty list) instead of the dict of all accumulated errors. Downstream, _set_keyspace_completed interprets this as success:

def _set_keyspace_completed(self, errors):
    if not errors:              # `not []` is True
        self._set_final_result(None)    # reports success
    else:
        self._set_final_exception(...)

This means keyspace changes can silently succeed from the driver's perspective even when some pools failed — partial failures are dropped.

Reproduction

tests/unit/test_cluster.py::SessionTest::test_set_keyspace_for_all_pools_reports_all_errors — this test expects the correct behavior but fails because of the bug. It was likely never run before against a compiled extension that exercised this code path with multiple pools.

Fix

callback(host_errors)callback(errors) on line 3442.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Fields

    No fields configured for Task.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions