You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[bug]: Public API work item list silently ignores unknown or unsupported query parameters (e.g. ?parent=) #10220
Searched on 2026-11-07 for list filter parent / filters api: no match. #5578 is a UI request about view filters on sub-issues.
Current behavior
GET /api/v1/workspaces/{slug}/projects/{project_id}/issues/?parent=<id> returns every work item of the project, as if the parameter did not exist. ?any_name_at_all=1 does the same. The Community list endpoint already refuses pql and filters with a clear 400 ("filter results client-side", IssueListCreateAPIEndpoint.get, line 392), so unsupported filtering is meant to fail loudly — but for every other name it fails silently. A client that filters by parent and trusts the response gets wrong data (for example, treats all items as children of one parent).
Either (preferred, small): answer 400 listing the unsupported parameters, like the existing pql/filters branch, using an allow-list of the parameters the endpoint really reads (per_page, cursor, order_by, fields, expand, external_id, external_source, …).
Or (feature): support a few cheap filters that make incremental sync possible without PQL: parent=<id> and updated_at__gte=<ISO datetime>. With the second one a mirror can fetch only what changed instead of listing all items on each run.
Implementation sketch (not tested against the Plane test suite)
Pinned to 618d0eb7. apps/api/plane/api/views/issue.py, IssueListCreateAPIEndpoint.get, next to the existing check at line 392:
Unknown parameter → 400 with its name in unsupported_parameters.
?parent=<id> → only that parent's children.
?updated_at__gte=<t> → only items changed after t, including items whose only change was a new comment (we measured that a new comment bumps the work item's updated_at, also on completed items).
Environment / Edition / Version
Self-hosted, Community, v1.4.3.
Workaround we use meanwhile
List everything (per_page=100) and filter on the client; compare updated_at per item to decide what to re-read.
I’d like to work on this. I plan to start with the preferred option: return a 400 listing unsupported query parameters, using an allow-list built from what the endpoint and paginator actually read. I’ll add tests for it. Is a 400 acceptable here, or would you rather have a softer behavior? I’ll treat the parent / updated_at__gte filters as a separate follow-up if you want them
PR is up: #10226. It returns a 400 listing the unsupported parameters, using an allow-list built from what the view, base class and paginator read (plus DRF's format), and it covers both the issues/ and work-items/ routes. Happy to adjust if you'd prefer a softer behavior than a hard 400.
Thanks for picking this up. Yes, a 400 is what I'd want. It's the behaviour the issue asks for and it matches the existing pql/filters branch.
Two things before merge:
In test_external_id_parameters_accepted there is a leftover block after the last assert: a loose docstring and a second GET with no assertion. It looks like an editing artefact and can be removed.
Activity
ShivamJuyal24 commentedon Nov 8, 2026
I’d like to work on this. I plan to start with the preferred option: return a 400 listing unsupported query parameters, using an allow-list built from what the endpoint and paginator actually read. I’ll add tests for it. Is a 400 acceptable here, or would you rather have a softer behavior? I’ll treat the parent / updated_at__gte filters as a separate follow-up if you want them
ShivamJuyal24 commentedon Nov 8, 2026
PR is up: #10226. It returns a 400 listing the unsupported parameters, using an allow-list built from what the view, base class and paginator read (plus DRF's
format), and it covers both theissues/andwork-items/routes. Happy to adjust if you'd prefer a softer behavior than a hard 400.pitupi commentedon Nov 8, 2026
Thanks for picking this up. Yes, a 400 is what I'd want. It's the behaviour the issue asks for and it matches the existing pql/filters branch.
Two things before merge:
In test_external_id_parameters_accepted there is a leftover block after the last assert: a loose docstring and a second GET with no assertion. It looks like an editing artefact and can be removed.
This is a visible change for clients that send parameters the endpoint has ignored so far (e.g. page and group_by, see Public API: project work-items list ignores ?page= and never terminates pagination (v1.3.0) #9340 and [bug]: Issue List API ignores group_by parameter and returns flat array with null grouped_by #9765). Could the PR description or release notes say so, so integrators know why they now get a 400?
The parent and updated_at__gte filters can stay out of this PR and be tracked separately.
ShivamJuyal24 commentedon Nov 8, 2026
Thanks for the review! I've made both changes:
GETrequest with no assertion) intest_external_id_parameters_accepted.pageorgroup_by, as requested.The full test suite in
test_issues.pypasses (15 tests), and bothruff checkandruff format --checkare clean. Let me know if it looks good to go!