Skip to content

ui-pagination-422-response#3641

Merged
crivetimihai merged 6 commits intomainfrom
bug/3469-ui-pagination-422-response
Mar 17, 2026
Merged

ui-pagination-422-response#3641
crivetimihai merged 6 commits intomainfrom
bug/3469-ui-pagination-422-response

Conversation

@Nayana-R-Gowda
Copy link
Copy Markdown
Collaborator

@Nayana-R-Gowda Nayana-R-Gowda commented Mar 12, 2026

Signed-off-by: NAYANA.R nayana.r7813@gmail.com

closes #3469

💡 Fix Description

Replaced hardcoded le=100/le=100 query constraints in several admin endpoints with settings.pagination_max_page_size.

Fix pagination validation limits causing 422 errors when UI selects per_page=200 or 500.

Previously several endpoints used a hardcoded validation limit:

le=100

which conflicted with Admin UI pagination options (200/500).

This change replaces the hardcoded limits with:

le=settings.pagination_max_page_size

so the API limit is configurable and consistent across endpoints.

🧪 Verification

Check Command Status
Lint suite make lint Pass
Unit tests make test Pass

📐 MCP Compliance (if relevant)

  • Matches current MCP spec
  • No breaking change to MCP clients

✅ Checklist

  • Code formatted (make black isort pre-commit)
  • No secrets/credentials committed

@crivetimihai crivetimihai added the bug Something isn't working label Mar 14, 2026
@crivetimihai crivetimihai added this to the Release 1.0.0 milestone Mar 14, 2026
@crivetimihai crivetimihai added the ui User Interface label Mar 14, 2026
@crivetimihai
Copy link
Copy Markdown
Member

Thanks @Nayana-R-Gowda — pagination 422 errors affect Admin UI usability. Targeting 1.0.0.

Nayana-R-Gowda and others added 4 commits March 17, 2026 09:57
Signed-off-by: NAYANA.R <nayana.r7813@gmail.com>
…outers

- Revert time_buckets le= back to 100 (visualization param, not pagination)
- Apply le=settings.pagination_max_page_size to llm_admin_router and
  llm_config_router pagination params that were missed

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Verify all modified endpoints use settings.pagination_max_page_size
and that time_buckets retains its le=100 visualization bound.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
…ings

- Remove unused `patch` import from test_pagination_bounds.py (ruff blocker)
- Update 12 observability endpoint docstrings that still referenced
  old (1-100) or (5-100) ranges after le= was changed to
  settings.pagination_max_page_size

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
crivetimihai
crivetimihai previously approved these changes Mar 17, 2026
Copy link
Copy Markdown
Member

@crivetimihai crivetimihai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Rebased onto main (clean, no conflicts) and reviewed thoroughly.

Original PR (commit by @Nayana-R-Gowda)

Correctly replaces hardcoded le=100 with le=settings.pagination_max_page_size across 18 locations in admin.py and 2 in teams.py. This fixes the 422 errors when the Admin UI selects per_page=200 or 500.

Review fixes applied (3 additional commits)

  1. Reverted time_buckets in get_latency_heatmap back to le=100 — this is a heatmap visualization granularity parameter, not pagination. Using pagination_max_page_size (configurable up to 10,000) would allow expensive histogram computations.

  2. Extended the fix to 4 missed pagination endpoints in llm_admin_router.py (2 endpoints) and llm_config_router.py (2 endpoints) that still had hardcoded le=100.

  3. Updated 12 stale docstrings in observability endpoints that still referenced old (1-100) / (5-100) ranges.

  4. Added 25 unit tests verifying every modified endpoint's le= metadata matches settings.pagination_max_page_size (or le=100 for time_buckets), plus 3 functional tests exercising endpoints with limit=200.

Security / Performance

  • No new attack surface. All endpoints remain behind require_permission().
  • The config bound (ge=1, le=10000) in config.py prevents unbounded values.
  • Database queries still apply LIMIT in SQL; only the validation cap changed.

Out of scope

  • Filed #3706 for 3 unused Pydantic schemas in schemas.py with hardcoded bounds (dead code).
  • Log search / observability routers intentionally use le=1000 (different domain, not affected by this bug).

All linters pass (black, isort, ruff, flake8). All 1181 relevant tests pass.

…akes

LoggingService.initialize() sets root logger to ERROR in CI. Tests using
caplog.at_level(WARNING) without a logger name target the root, which
gets overridden. Specify the exact logger name so caplog sets the level
on the correct logger regardless of root configuration.

Fixes 6 flaky CI failures in test_passthrough_headers,
test_passthrough_headers_fixed, and test_websocket_transport.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
test_cache_expiry used asyncio.sleep(1.1) to wait for a 1s TTL, which
is flaky under CI load. Mock time.time() and advance it deterministically
instead. Also eliminates the 1.1s test runtime.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
@crivetimihai crivetimihai merged commit 5e88ceb into main Mar 17, 2026
39 checks passed
@crivetimihai crivetimihai deleted the bug/3469-ui-pagination-422-response branch March 17, 2026 18:05
calculus-ask pushed a commit to calculus-ask/mcp-context-forge that referenced this pull request Mar 18, 2026
* ui-pagination-422-response

Signed-off-by: NAYANA.R <nayana.r7813@gmail.com>

* fix: revert non-pagination time_buckets bound and extend fix to LLM routers

- Revert time_buckets le= back to 100 (visualization param, not pagination)
- Apply le=settings.pagination_max_page_size to llm_admin_router and
  llm_config_router pagination params that were missed

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* test: add differential tests for pagination bounds (IBM#3469)

Verify all modified endpoints use settings.pagination_max_page_size
and that time_buckets retains its le=100 visualization bound.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* fix: address codex review — remove unused import, update stale docstrings

- Remove unused `patch` import from test_pagination_bounds.py (ruff blocker)
- Update 12 observability endpoint docstrings that still referenced
  old (1-100) or (5-100) ranges after le= was changed to
  settings.pagination_max_page_size

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* fix(tests): use explicit logger names in caplog.at_level to fix CI flakes

LoggingService.initialize() sets root logger to ERROR in CI. Tests using
caplog.at_level(WARNING) without a logger name target the root, which
gets overridden. Specify the exact logger name so caplog sets the level
on the correct logger regardless of root configuration.

Fixes 6 flaky CI failures in test_passthrough_headers,
test_passthrough_headers_fixed, and test_websocket_transport.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* fix(tests): replace sleep-based cache expiry test with time mock

test_cache_expiry used asyncio.sleep(1.1) to wait for a 1s TTL, which
is flaky under CI load. Mock time.time() and advance it deterministically
instead. Also eliminates the 1.1s test runtime.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

---------

Signed-off-by: NAYANA.R <nayana.r7813@gmail.com>
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Co-authored-by: Mihai Criveti <crivetimihai@gmail.com>
Signed-off-by: KRISHNAN, SANTHANA <sk8069@exo.att.com>
Signed-off-by: calculus-ask <a.santhana.k@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ui User Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG][UI]: Pagination per_page options 200/500 exceed API limit of 100

2 participants