-
Notifications
You must be signed in to change notification settings - Fork 46
Description
π Bug Report
Repository: hatnote/montage
File: montage/rdb.py
Line: 1138β1143
Severity: High β Incorrect data in campaign reports
Summary
The get_campaign_rounds() method in CoordinatorDAO (inside rdb.py) has a silent logic bug: it calls .filter() and .order_by() on a SQLAlchemy query object but never reassigns the result back to q. Since SQLAlchemy query refinements return a new query object (they are non-mutating), the filter and ordering are silently discarded. As a result:
- Cancelled rounds are always included, even when
with_cancelled=Falseis explicitly passed. - Rounds are never sorted by
create_dateβ the order is undefined/database-dependent.
This bug has serious downstream impact in build_campaign_report() (line 2176β2178), which passes with_cancelled=False and then trusts rnds[-1] to be the most recently created, non-cancelled round. Because neither the filter nor the ordering is applied, rnds[-1] may be a cancelled round or a round in an unexpected position, causing the entire campaign report to be built against the wrong round.
Buggy Code
# montage/rdb.py, lines 1138β1143
def get_campaign_rounds(self, campaign, with_cancelled=False):
q = self.query(Round).filter_by(campaign=campaign)
if not with_cancelled:
q.filter(Round.status != CANCELLED_STATUS) # β Bug: result is discarded
q.order_by(Round.create_date) # β Bug: result is discarded
return q.all()