fix(platform)!: drop inert OData params from list_records - #1877
Conversation
The Data Fabric read endpoint (GET .../EntityService/entity/{key}/read)
implements only start, limit and expansionLevel. It accepts $filter,
$orderby, $select and $expand, then silently ignores them and returns the
full unfiltered set. Verified against a live tenant: a filter matching
nothing still returned all 32 records, as did deliberately malformed
filter syntax, and $select left every column in place. There is no v2
read endpoint that honours them.
The four params were added in #1616 alongside the structured query API.
Their test asserted only that httpx received them under a mock, so it
could not catch that the server drops them. The docstring advertised
them as OData support, making the failure mode a silent wrong answer:
a filtered query returning every record.
Remove them, restoring the pre-#1616 surface plus expansion_level, which
does work. Filtering, sorting and projection belong to retrieve_records
(POST .../query), which genuinely filters.
BREAKING CHANGE: list_records() and list_records_async() no longer accept
filter, orderby, select or expand. Passing them now raises TypeError
instead of silently returning unfiltered records. Use retrieve_records()
with an EntityQueryFilterGroup instead.
Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR removes OData-related parameters from EntitiesService.list_records / list_records_async in uipath-platform because the underlying Data Fabric /read endpoint accepts those params but silently ignores them, creating a “silent wrong answer” failure mode. The change narrows the public API to the parameters the endpoint actually honors (paging + expansion), updates documentation/examples to route filtering/sorting/projection to the structured query API, and adjusts tests accordingly.
Changes:
- Drop inert
filter,orderby,select,expandkwargs from sync/asynclist_recordsand from the internal request spec builder. - Update docs/examples to point filtering/sorting/projection to
retrieve_records(POST .../query) instead oflist_records. - Update unit test assertions to ensure only paging/expansion params are sent; bump
uipath-platformversion.
File summaries
| File | Description |
|---|---|
packages/uipath-platform/src/uipath/platform/entities/_entity_data_service.py |
Removes OData kwargs from internal list methods/spec; documents why OData params are not sent. |
packages/uipath-platform/src/uipath/platform/entities/_entities_service.py |
Removes OData kwargs from the public facade; updates docstrings/examples to use retrieve_records. |
packages/uipath-platform/tests/services/test_entities_service.py |
Updates the list-records test to assert only paging/expansion params are sent. |
packages/uipath-platform/pyproject.toml |
Bumps the uipath-platform package version. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The lint jobs run `uv sync --locked`, which fails while the lockfiles still pin uipath-platform 0.2.22. Only the version line is touched in each lock — `uv lock --check` passes on both. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
Addresses review feedback: the wire-level assertion showed no $-params are sent, but nothing pinned the caller-facing contract. Parametrized test asserts filter/orderby/select/expand each raise TypeError, so the params cannot quietly return — including via a future **kwargs. Also corrects the section header above list_records, which still described the method as a "multi-record read with OData filters". Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
|
🚨 Heads up:
|



Problem
EntitiesService.list_recordsadvertises OData filtering:The endpoint it calls —
GET datafabric_/api/EntityService/entity/{key}/read— does not implement it. It accepts$filter,$orderby,$selectand$expand, ignores them, and returns the full unfiltered set. The failure mode is a silent wrong answer: a filtered query returns every record, with no error.Verified against a live tenant (
TestEntity, 32 records), via the SDK and rawhttpx:$filter=Name eq '<one real match>'$filter=Name eq 'definitely-no-such-value-xyz'$filter=bogus syntax ((($select=Name$orderby=Name descfilter=…(no$) /query=…What the endpoint does honour:
startstart=30→ 2 of 32;start=100→ 0limit1/2/31→ exact;1000→ 32;0→ 32 (treated as unset);-1→ HTTP 400Invalid limit -1expansionLevel0→ bare guid,1→{Id},2→ full nested recordGET api/v2/.../readreturns 404, so there is no newer read endpoint these params were written against.Why CI didn't catch it
The four params were added in #1616 alongside the (working) structured query API. The covering test asserted only that
pytest-httpxreceived them:That passes whether or not the server implements any of it — the mock replies with whatever the test told it to.
Change
Remove
filter,orderby,selectandexpandfromlist_records/list_records_asyncand from_list_records_spec. This restores the pre-#1616 parameter surface (entity_key,schema,start,limit) plusexpansion_level, which does work — nothing that ever functioned is lost.Filtering, sorting and projection already have a working home in
retrieve_records(POST .../query,EntityQueryFilterGroup); docstrings and examples now point there._list_records_specrecords why the params are not sent, so they don't get re-added.The test now asserts the positive contract and the negative one:
Note for reviewers: filtering a related entity's field via
retrieve_recordsneedsfield_name="Rel.Id"andexpansion_level>=1, otherwise the backend rejects it with "Filtering or sorting fields from related entities has to be expanded in the query". Filtering on the bare relationship name (CreatedBy eq '<guid>') is silently ignored — same class of trap, on the endpoint that otherwise works.Verification
Live tenant, with this branch's source:
uipath-platformsuite passes,ruff check/ruff format --checkclean,mypy srcclean (163 files).Breaking change
list_records()/list_records_async()no longer acceptfilter,orderby,selectorexpand. Passing them raisesTypeErrorinstead of silently returning unfiltered records. Callers migrate toretrieve_records()with anEntityQueryFilterGroup.Happy to swap this for a deprecation window (keep the params, raise
NotImplementedError) if reviewers prefer a softer landing.🤖 Generated with Claude Code