Skip to content

get_campaign_rounds() silently ignores with_cancelled filter and orderingΒ #399

@Anujkumar9081

Description

@Anujkumar9081

πŸ› 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:

  1. Cancelled rounds are always included, even when with_cancelled=False is explicitly passed.
  2. 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()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions