services/project_list_enrichment._latest_succeeded_scan_id_map builds WHERE scans.project_id IN (...) with one bind parameter per project. A super admin sees every project, so past 32,767 of them the query is rejected before it runs:
asyncpg.exceptions._base.InterfaceError: the number of query arguments cannot exceed 32767
[SQL: SELECT DISTINCT ON (scans.project_id) scans.id FROM scans WHERE scans.project_id IN ($2::UUID, ...
This is the same ceiling #152 cleared for _current_scan_ids in the inventory path, where the predicate now switches to a single array parameter above a threshold. The helper here was not covered by that change, and the dashboard and the project list both call it, so the portfolio grid and the project list fail together for an operator with a large enough estate.
Surfaced by tests/unit/services/test_dashboard_service.py::test_super_admin_sees_all_teams against a local database that had accumulated 36,905 projects over repeated suite runs. That is an artefact of a shared test database rather than a seeded case, but the query it produced is the one a real deployment produces at the same size, and the ceiling is the driver's, not the test's.
Worth checking the other helpers that take an id list the same way while fixing this one: the pattern is "collect ids in Python, hand them to IN", and the earlier fix suggests it is not limited to these two sites.
services/project_list_enrichment._latest_succeeded_scan_id_mapbuildsWHERE scans.project_id IN (...)with one bind parameter per project. A super admin sees every project, so past 32,767 of them the query is rejected before it runs:This is the same ceiling #152 cleared for
_current_scan_idsin the inventory path, where the predicate now switches to a single array parameter above a threshold. The helper here was not covered by that change, and the dashboard and the project list both call it, so the portfolio grid and the project list fail together for an operator with a large enough estate.Surfaced by
tests/unit/services/test_dashboard_service.py::test_super_admin_sees_all_teamsagainst a local database that had accumulated 36,905 projects over repeated suite runs. That is an artefact of a shared test database rather than a seeded case, but the query it produced is the one a real deployment produces at the same size, and the ceiling is the driver's, not the test's.Worth checking the other helpers that take an id list the same way while fixing this one: the pattern is "collect ids in Python, hand them to
IN", and the earlier fix suggests it is not limited to these two sites.