gitlabhq/gitlabhq · error · DeploymentsFinder::InefficientQueryError
`updated_at` filter requires `updated_at` sort
Error message
`updated_at` filter requires `updated_at` sort
What it means
DeploymentsFinder#validate! raises InefficientQueryError when the updated_at filter is present but the sort is not order_by=updated_at. The filter only stays efficient when results are scanned in updated_at order via its supporting index, so GitLab requires sort and filter to match and returns HTTP 400 otherwise.
Source
Thrown at app/finders/deployments_finder.rb:61
def execute
items = init_collection
items = by_updated_at(items)
items = by_finished_at(items)
items = by_environment(items)
items = by_status(items)
items = preload_associations(items)
sort(items)
end
private
def validate!
if filter_by_updated_at? && filter_by_finished_at?
raise InefficientQueryError, 'Both `updated_at` filter and `finished_at` filter can not be specified'
end
if filter_by_updated_at? && !order_by_updated_at?
raise InefficientQueryError, '`updated_at` filter requires `updated_at` sort'
end
if filter_by_finished_at? && !order_by_finished_at?
raise InefficientQueryError, '`finished_at` filter requires `finished_at` sort.'
end
if order_by_finished_at? && !(filter_by_finished_at? || filter_by_finished_statuses?)
raise InefficientQueryError,
'`finished_at` sort requires `finished_at` filter or a filter with at least one of the finished statuses.'
end
if filter_by_finished_at? && !filter_by_successful_deployment?
raise InefficientQueryError, '`finished_at` filter must be combined with `success` status filter.'
end
if filter_by_environment_name? && !params[:project].present?
raise InefficientQueryError, '`environment` name filter must be combined with `project` scope.'
endView on GitHub (pinned to 55ee20384a)
Solutions
- Add order_by=updated_at (with sort=asc or sort=desc) whenever you send updated_after/updated_before.
- If you must keep a different sort, drop the updated_at filter entirely.
- Use the updated_at ordering together with keyset pagination for large result sets.
Example fix
# before GET /api/v4/projects/42/deployments?updated_after=2026-01-01T00:00:00Z # => 400 `updated_at` filter requires `updated_at` sort # after GET /api/v4/projects/42/deployments?updated_after=2026-01-01T00:00:00Z&order_by=updated_at&sort=desc
Defensive patterns
Strategy: validation
Validate before calling
if params[:updated_after] || params[:updated_before] params[:order_by] ||= 'updated_at' raise ArgumentError, 'updated_at filter needs order_by=updated_at' unless params[:order_by] == 'updated_at' end
Prevention
- Bind time filters and sort in one request-builder method so they cannot diverge.
- Disallow user-supplied order_by when a time filter is active.
- Cover filter+sort combinations in client contract tests.
When it happens
Trigger: GET /api/v4/projects/:id/deployments?updated_after=... sent without order_by, or with order_by=id / order_by=finished_at; SDK defaults that force order_by=id; pagination params copied from another endpoint.
Common situations: Clients adding time filters to an existing sorted listing; GraphQL/Automation templates that preset a default sort; keyset pagination code that sets its own order_by.
Related errors
- `finished_at` filter requires `finished_at` sort.
- `finished_at` sort requires `finished_at` filter or a filter
- Both `updated_at` filter and `finished_at` filter can not be
- `finished_at` filter must be combined with `success` status
- `environment` name filter must be combined with `project` sc
AI-assisted analysis of gitlabhq/gitlabhq@55ee20384a (2026-08-21).
Data as JSON: /api/errors/e672fc10a2a6682c.
Report an issue: GitHub.