Since farmOS 4.0.5, every filter[...] on asset, log and quantity collections through JSON:API returns HTTP 200 with an empty data array for an OAuth2 user holding the Farm Manager role, whatever the filter says. Unfiltered reads, sort and page[offset] work; an unknown field still returns a 400. Taxonomy term and file collections filter normally. Reproduced on 2026-09-22 against our instance (4.0.5) with an exact-name filter on a land asset that an unfiltered read returns one request earlier, and with a not-equal filter that should match every row.
Cause, as far as we can trace it: farmOS 4.0.5 updates the Entity API module to 1.8 (SA-CONTRIB-2026-113). Its commit c07395aa (“fix: Update JSONAPI filtering”) removes the branch in entity_jsonapi_entity_filter_access() that granted JSONAPI_FILTER_AMONG_ALL when the query-access handler returned no conditions. Assets, logs and quantities use Entity API’s query access handler; for a manager the conditions are empty (the account has view any asset), so the hook now returns nothing, core’s generic rule then requires the entity type’s admin permission (administer assets, administer log, administer quantity), the managed roles do not hold it, and TemporaryQueryGuard appends alwaysFalse().
Effect: any integration that filters assets or logs through JSON:API with a manager, worker or viewer token stops seeing data, silently. Our MCP server, and any farmOS client using filter[name] to resolve an asset before a write, is affected.
Possible fixes upstream: implement hook_jsonapi_entity_filter_access() for asset, log and quantity in farmOS, granting JSONAPI_FILTER_AMONG_ALL to accounts with the view any <type>permission (mirroring what Entity API 1.7 did), or add the admin permissions to the managed roles’ “view all” setting.
We have worked around it client-side (unfiltered paginated reads, matched in memory). Happy to test a fix.
Thanks for reporting this @agnes! I’m surprised our tests didn’t catch it.
The Entity API module’s release notes hinted at this:
This release changes JSONAPI entity collection access control. In certain circumstances this may mean that JSONAPI clients can access less data than expected. Sites should carefully review their JSONAPI integrations and implement their own json api filter access rules if necessary. See examples in jsonapi module in core on how to do so for your own entity types: https://git.drupalcode.org/project/drupal/-/blob/main/core/modules/jsona…
I re-ran the same checks from the original report against our instance (margregen.farmos.net) this morning, authenticated by OAuth2 password grant with the farm_manager scope, the same way our integration connects. Every filter that returned an empty list before now returns the right rows.
What I tried
Before
Now
/api/asset/land?filter[name]=Paddock 2
0
1
filter[name][value]=…&filter[name][operator]==
0
1
filter[name][condition][path]=name&…[value]=…
0
1
/api/asset/plant?filter[name]=20 MAR 2025 - Comfrey - P2R1.0-3
0
1
/api/log/activity?filter[name]=Note — NURS.GR
0
1
/api/asset/plant?filter[archived]=0 / =1
0 / 0
5 / 5
/api/asset/land?filter[bogusfield]=x
400
400 (still correctly refused)
I also checked the patterns our own integration actually depends on, which the original report did not cover, since those are what broke in practice:
What I tried
Now
filter[name][operator]=CONTAINS on plant names (species search)
5 rows
filter[name][operator]=CONTAINS on land names (section search)
That last one is worth flagging back to you: the nested relationship filter works against real data, so the refactor you did after the discussion with @paul121 and @symbioquine holds up outside the test suite.
Thanks again for turning this round so quickly, and for the extra test coverage in the OAuth2 token context — that is the context we actually run in, so it matters to us more than the default one.