Summary
Both the GitLab and GitHub providers' internal get() helper read both pagination keys unconditionally:
if pagination:
params["per_page"] = str(pagination["per_page"])
params["page"] = str(pagination["cursor"])
PaginationParams is declared total=False, so both per_page and cursor are optional. A caller (including an external RPC client) can legitimately send a type-valid partial dict such as {"per_page": 50} or {"cursor": "2"}, which raises KeyError instead of paginating with server defaults.
Affected code
src/scm/providers/gitlab/provider.py — get()
src/scm/providers/github/provider.py — get()
This is not specific to any single endpoint. pagination flows from the public action API (actions.py) and across the RPC boundary directly into get(), so every paginated endpoint on both providers is affected (e.g. get_tree, get_readme, get_pull_request_template, get_repository_assignees, etc.).
Impact
A client sending a partial PaginationParams dict — which the type contract permits — triggers an unhandled KeyError rather than a successful paginated request.
Reproduction
Call any paginated provider method with only one pagination key:
provider.get_tree("deadbeef", pagination={"per_page": 50}) # KeyError: 'cursor'
provider.get_tree("deadbeef", pagination={"cursor": "2"}) # KeyError: 'per_page'
Proposed fix
Forward only the keys actually present, letting GitLab/GitHub apply their server-side defaults for the missing one:
if pagination:
if "per_page" in pagination:
params["per_page"] = str(pagination["per_page"])
if "cursor" in pagination:
params["page"] = str(pagination["cursor"])
Apply to both providers' get() helper. A regression test passing each key in isolation (asserting only the corresponding query param is sent) would lock in the behavior.
Summary
Both the GitLab and GitHub providers' internal
get()helper read both pagination keys unconditionally:PaginationParamsis declaredtotal=False, so bothper_pageandcursorare optional. A caller (including an external RPC client) can legitimately send a type-valid partial dict such as{"per_page": 50}or{"cursor": "2"}, which raisesKeyErrorinstead of paginating with server defaults.Affected code
src/scm/providers/gitlab/provider.py—get()src/scm/providers/github/provider.py—get()This is not specific to any single endpoint.
paginationflows from the public action API (actions.py) and across the RPC boundary directly intoget(), so every paginated endpoint on both providers is affected (e.g.get_tree,get_readme,get_pull_request_template,get_repository_assignees, etc.).Impact
A client sending a partial
PaginationParamsdict — which the type contract permits — triggers an unhandledKeyErrorrather than a successful paginated request.Reproduction
Call any paginated provider method with only one pagination key:
Proposed fix
Forward only the keys actually present, letting GitLab/GitHub apply their server-side defaults for the missing one:
Apply to both providers'
get()helper. A regression test passing each key in isolation (asserting only the corresponding query param is sent) would lock in the behavior.