Detail Bug Report
https://app.detail.dev/org_5f375fe3-a706-4e9a-a6f7-800f2439b3f6/bugs/bug_b524d258-a726-4b84-987a-1d2c5774cfd5
Introduced in #282 by @sachiniyer on May 6, 2026
Summary
- Context: The
scans list command with filters (--status, --scan-type, --since, --until) performs client-side pagination after filtering
- Bug: Requested page number is not validated against filtered result count, allowing impossible pagination state where page number exceeds total pages
- Actual vs. expected: When filtering reduces total pages below requested page, displays "Page: X of Y" where X > Y. Should clamp to valid range or show page Y
- Impact: Confusing user experience with empty results showing impossible pagination like "Page: 5 of 1"
Code with Bug
// src/commands/scans.rs lines 150-161
if needs_full_fetch {
let all = fetch_all_scans(&client, &repo_id).await?;
let filtered = filter_scans(
&all,
status.as_ref(),
scan_type.as_ref(),
since_ms,
until_ms,
);
let total = filtered.len();
let page_items = paginate_items(&filtered, *page, *limit); // <-- BUG 🔴 page not validated against filtered total
output_list(&page_items, total, *page, *limit, format)
}
// src/commands/bugs.rs lines 577-578
let page_items = paginate_items(&filtered, *page, *limit); // <-- BUG 🔴 same missing page validation
output_list(&page_items, total, *page, *limit, format)
Explanation
When filters are used, the CLI fetches all items, filters them client-side, then paginates the filtered list. If the user requests a page that was valid before filtering (e.g., page 2 of all results) but the filter reduces the result set to fewer pages (e.g., only 1 page), paginate_items uses the requested page to compute an offset beyond the end of the filtered list, returning an empty set. output_list still prints pagination metadata based on the filtered total, producing an impossible state like "Page: 2 of 1".
Codebase Inconsistency
The unfiltered path uses server-side pagination:
let scans = client.list_scans(&repo_id, *limit, offset).await?;
output_list(&scans.scans, usize::try_from(scans.total.max(0)).unwrap_or(0), *page, *limit, format)
The API returns a consistent total for the query and does not produce "page > total pages" states, while the filtered (client-side) path does.
Recommended Fix
Before calling paginate_items/output_list on the filtered path, clamp the requested page to the maximum page implied by the filtered total and limit (preferably by reusing the existing total_pages logic in src/output.rs). Apply the same change to scans list and bugs list.
History
This bug was introduced in commit 6ab434c. The commit added client-side filtering support (--status, --scan-type, --since, --until) to the scans list command. Since the scans API lacks server-side filtering, the implementation fetches all scans, filters them client-side, then re-paginates. The bug slipped in because the re-pagination logic at line 161 (paginate_items(&filtered, *page, *limit)) didn't validate that the requested page number was valid for the filtered result size, creating the impossible pagination state where page number exceeds total pages.
Detail Bug Report
https://app.detail.dev/org_5f375fe3-a706-4e9a-a6f7-800f2439b3f6/bugs/bug_b524d258-a726-4b84-987a-1d2c5774cfd5
Introduced in #282 by @sachiniyer on May 6, 2026
Summary
scans listcommand with filters (--status,--scan-type,--since,--until) performs client-side pagination after filteringCode with Bug
Explanation
When filters are used, the CLI fetches all items, filters them client-side, then paginates the filtered list. If the user requests a page that was valid before filtering (e.g., page 2 of all results) but the filter reduces the result set to fewer pages (e.g., only 1 page),
paginate_itemsuses the requested page to compute an offset beyond the end of the filtered list, returning an empty set.output_liststill prints pagination metadata based on the filteredtotal, producing an impossible state like "Page: 2 of 1".Codebase Inconsistency
The unfiltered path uses server-side pagination:
The API returns a consistent
totalfor the query and does not produce "page > total pages" states, while the filtered (client-side) path does.Recommended Fix
Before calling
paginate_items/output_liston the filtered path, clamp the requested page to the maximum page implied by the filteredtotalandlimit(preferably by reusing the existingtotal_pageslogic insrc/output.rs). Apply the same change toscans listandbugs list.History
This bug was introduced in commit 6ab434c. The commit added client-side filtering support (
--status,--scan-type,--since,--until) to thescans listcommand. Since the scans API lacks server-side filtering, the implementation fetches all scans, filters them client-side, then re-paginates. The bug slipped in because the re-pagination logic at line 161 (paginate_items(&filtered, *page, *limit)) didn't validate that the requested page number was valid for the filtered result size, creating the impossible pagination state where page number exceeds total pages.