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
fix: apify-api-read/write coerce query values before validation #1716
apify-api-write (src/tools/api/apify_api_write.ts:116) and apify-api-read (src/tools/api/apify_api_read.ts:48) validate with compileSchema, the shared AJV instance with coerceTypes: 'array'. The query schema is record<string, string | number | boolean>, so AJV changes invalid values into valid ones and does not reject them:
{"query": {"deleteAll": null}} is sent as deleteAll= (null becomes "")
{"query": {"limit": [10]}} is sent as limit=10 (a one-item array becomes a scalar)
The call should fail input validation instead.
send-server-actor-request (#1681) already avoids this with its own new Ajv({ coerceTypes: false, ... }). Do the same for both API tools, or add a non-coercing compileSchema variant in src/utils/ajv.ts. Add a unit test for each tool to show that null and array query values are rejected.
Reproduced with a unit test that captures the outgoing request:
apify-api-read {"path":"/v2/datasets","query":{"limit":[10],"desc":null}} is sent as https://api.apify.com/v2/datasets?limit=10&desc=
apify-api-write {"path":"/v2/datasets/abc","method":"DELETE","query":{"deleteAll":null,"limit":[10]}} is sent as https://api.apify.com/v2/datasets/abc?deleteAll=&limit=10
[10] becomes the string "10" (the string branch of the union is tried first); the URL is the same. send_server_actor_request.ts:490 rejects both values.
Notes for the fix:
A non-coercing variant in src/utils/ajv.ts must keep the removeKeyword('pattern' | 'patternProperties' | 'format') hardening from ajv.ts:15-17.
Don't switch send-server-actor-request to the new helper in this PR.
With coercion off, a non-string path (e.g. 123) is also rejected instead of becoming "123". That is expected.
Tests: ajvValidate returns false for query: {x: null} and query: {x: [10]} on each tool, and a valid query: {limit: 10, desc: true, format: 'json'} still passes.
Activity