SG Ground Truth

sort fails silently

A sort on an unknown or unsortable field answers 200 with the rows in default order, while the same field name in a filter answers 400 and names the reason.

Kind
The behaviour should change
Status
unreported
Confirmed
2026-09-04
API

Expected A sort naming a field that does not exist, or one whose data_type cannot be sorted, is rejected the way the same name is rejected in a filter.

Actual One request, two parameters, two contracts. Every row below is the same field name sent against the same type:

field in sort in a filter
sg_not_a_field_at_all 200, rows in default order 400 API read() Version.sg_not_a_field_at_all doesn't exist.
open_notes_count (summary) 200, rows in default order 400 API read() Version.open_notes_count's 'summary' data type cannot be used in a filter.
sg_uploaded_movie (url) 200, rows in default order 400 API read() Version.sg_uploaded_movie's 'url' data type cannot be used in a filter.

Only the syntax of sort is validated, and there it is exact:

sent result
sort= 400 {"sort": ["sort must be filled"]}
sort=id desc 400 {"sort": ["sort list is not valid"]}
sort=+id 400 {"sort": ["sort list is not valid"]}
"sort": [{"field_name": "id", "direction": "desc"}] on _search 400 {"sort": ["sort array is not valid"]}

An accepted-and-ignored sort returns the default order, which is id ascending. A caller sorting ascending on a mistyped field gets a response indistinguishable from a working one.

Reproduce

curl -sS "$SITE/api/v1/entity/versions?sort=sg_not_a_field_at_all&page[size]=5" \
  -H "Authorization: Bearer $TOKEN" | head
# 200, rows id ascending

curl -sS "$SITE/api/v1/entity/versions?filter[sg_not_a_field_at_all]=x" \
  -H "Authorization: Bearer $TOKEN"
# 400 API read() Version.sg_not_a_field_at_all doesn't exist.

Impact Nothing in the response says the sort was dropped, so a client cannot detect it and a test asserting on ordering passes against id ascending whenever that is what the intended sort would have produced. The cost lands on whoever reads the output: a page of "most recent" that is oldest first, with a 200 behind it. Guarding against it means fetching /schema/<Type>/fields and validating every sort key before the read, which is the expensive call.

Proposed change Reject an unknown or unsortable sort field with the 400 the same name already produces in a filter. The message exists and names the field and the data_type, so the validation is a matter of applying it on the other parameter.

Every entry on this site is the output of a probe in probes/. The corpus is generated by running those probes against a live Flow Production Tracking site, not written from memory.

Not affiliated with or endorsed by Autodesk. Flow Production Tracking is their product; this is an independent record of how its REST API answers.