Skip to content

docs(openapi): Autofix OpenAPI spec validation errors#2754

Merged
Pijukatel merged 3 commits into
masterfrom
claude/openapi-errors-fix-or76l8
Jul 10, 2026
Merged

docs(openapi): Autofix OpenAPI spec validation errors#2754
Pijukatel merged 3 commits into
masterfrom
claude/openapi-errors-fix-or76l8

Conversation

@Pijukatel

@Pijukatel Pijukatel commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Autogenerated OpenAPI fixes suggestions based on validation errors generated from running API integration tests with OpenAPI validator turned on.

Error log: Production OpenAPI response-validation errors from apify-api (Jul 8, 2026)

apify-core version: https://github.com/apify/apify-core/commit/abeddcb4b7b3dee66ea2169435153144dae91c19

Detailed changes description

Error fixes

Missing 402 on Actor task run endpoints

Files: apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@runs.yaml (post.responses), apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync-get-dataset-items.yaml (get.responses, post.responses)
Error: no schema defined for status code '402' in the openapi spec (POST /v2/actor-tasks/{actorTaskId}/runs, GET /v2/actor-tasks/{actorTaskId}/run-sync-get-dataset-items)
Root cause: Task run creation goes through run-limit checks that throw notEnoughUsageToRunPaidActor / memory / concurrency errors with HTTP 402. Both run-sync variants launch a run and hit the same checks.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/actor-server/src/actor_jobs/run_limits_helper.ts#L194

Missing 402 on storage read endpoints (x402 payment reuse)

Files: apify-api/openapi/components/objects/datasets/dataset.yaml, .../datasets/dataset-statistics.yaml, .../datasets/dataset-items.yaml, .../key-value-stores/key-value-store.yaml, .../key-value-stores/key-value-store-keys.yaml, .../key-value-stores/key-value-store-record.yaml, .../request-queues/request-queue.yaml, .../request-queues/request-queue-head.yaml, .../request-queues/request-queue-requests.yaml, .../request-queues/request-queue-request.yaml (all in the shared GET response blocks)
Error: no schema defined for status code '402' in the openapi spec (observed on GET /v2/datasets/{datasetId}/items; applies to storage reads generally)
Root cause: The agentic-payment middleware runs on every request, but only emits 402 when the caller participates in x402 payment. A new x402 payment must be initiated on an Actor execution route; reusing an already-initiated payment to read a run's results is permitted on any route, and the reuse check returns 402 on a non-execution (storage) route. Consequently any storage GET (read) can return 402. 402 was added to the shared GET blocks of datasets, key-value stores, and request queues - read operations only, not writes - which also covers the default and last-run storage variants (e.g. /v2/actor-runs/{runId}/dataset/items).
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/agentic-payments/src/x402/x402_client.ts#L873

Missing 401 on POST /v2/actors/{actorId}/run-sync-get-dataset-items

Files: apify-api/openapi/paths/actors/acts@{actorId}@run-sync-get-dataset-items.yaml (post.responses)
Error: no schema defined for status code '401' in the openapi spec (POST /v2/actors/{actorId}/run-sync-get-dataset-items)
Root cause: The operation inherits global bearer/api-key security; an invalid token is rejected with 401 by the auth middleware. The GET sibling already documented 401, the POST did not.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/api/src/routes/routes_config.ts#L648

Missing 401 on GET /v2/store

Files: apify-api/openapi/paths/store/store.yaml (get.responses)
Error: no schema defined for status code '401' in the openapi spec (GET /v2/store)
Root cause: The global auth middleware validates any supplied token before the route runs, so passing an invalid token to store search returns 401.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/api/src/middleware/authentication.ts#L91

Missing 401 on GET /v2/actors/{actorId}/builds/default

Files: apify-api/openapi/paths/actors/acts@{actorId}@builds@default.yaml (get.responses)
Error: no schema defined for status code '401' in the openapi spec (GET /v2/actors/{actorId}/builds/default)
Root cause: Although the endpoint does not require a token (security: []), the auth middleware still validates any token that is supplied and returns 401 for an invalid one - the same reason the file already documents 403. security: [] is left unchanged; only the response is documented.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/api/src/routes/routes_config.ts#L521

options.maxTotalChargeUsd must be nullable

Files: apify-api/openapi/components/schemas/actor-runs/RunOptions.yaml
Error: type.openapi.validation: must be number at /response/data/options/maxTotalChargeUsd (POST /v2/actor-runs/{runId}/abort)
Root cause: maxTotalChargeUsd is an optional run option that is only stored when truthy, so runs created without it surface null. Changed to type: [number, "null"] to match the sibling maxItems field.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/schemas/src/actors.ts#L97

options.maxItems minimum lowered to 0

Files: apify-api/openapi/components/schemas/actor-runs/RunOptions.yaml
Error: minimum.openapi.validation: must be >= 1 at /response/data/options/maxItems (POST /v2/actor-runs/{runId}/resurrect)
Root cause: The API defines maxItems with min 0 and treats 0 as a valid sentinel; the spec's minimum: 1 was stricter than the API. Lowered to 0.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/schemas/src/actors.ts#L94

stats.deleteCount / stats.listCount no longer required

Files: apify-api/openapi/components/schemas/key-value-stores/KeyValueStoreStats.yaml
Error: required.openapi.validation: must have required property 'deleteCount' / 'listCount' at /response/data/stats (POST /v2/key-value-stores)
Root cause: The stats serializer picks only present fields and the DB marks every counter optional, so a pre-existing (get-or-create) store can omit deleteCount/listCount. Removed them from required.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/api/src/lib/key_value_stores.ts#L682

proxy no longer required on GET /v2/users/me

Files: apify-api/openapi/components/schemas/users/UserPrivateInfo.yaml
Error: required.openapi.validation: must have required property 'proxy' at /response/data/proxy (GET /v2/users/me)
Root cause: proxy is only attached when the user has proxy USE permission; otherwise the key is omitted. Removed from required.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/api/src/routes/users/user.ts#L84

requestUrl must be nullable

Files: apify-api/openapi/components/schemas/webhooks/Webhook.yaml
Error: type.openapi.validation: must be string at /response/data/requestUrl (GET /v2/webhooks/{webhookId}, POST /v2/webhooks)
Root cause: requestUrl is modeled as nullish and is only meaningful for HTTP-request webhooks; other action types (Slack, email, etc.) return null. Changed to type: [string, "null"].
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/zod-types/src/common/webhooks.ts#L57

currentPricingInfo no longer required on store items

Files: apify-api/openapi/components/schemas/store/StoreListActor.yaml
Error: required.openapi.validation: must have required property 'currentPricingInfo' at /response/data/items/{i}/currentPricingInfo (GET /v2/store)
Root cause: The Recombee-backed store search maps items without a currentPricingInfo field, so it is not guaranteed. Removed from required.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/actor-server/src/recombee/recombee_store_search.ts#L183

notice must be nullable (store items and actor)

Files: apify-api/openapi/components/schemas/store/StoreListActor.yaml, apify-api/openapi/components/schemas/actors/Actor.yaml
Error: type.openapi.validation: must be string at /response/data/items/{i}/notice (GET /v2/store) and /response/data/notice (GET /v2/actors/{actorId})
Root cause: notice is modeled as string | null in the data layer and coalesced to null when absent. Made nullable in both (independent) schemas.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/types/src/recombee.ts#L34

Issues

Partially implements: #2286

claude added 2 commits July 9, 2026 13:16
Add error responses that the live API returns but the spec did not document,
each surfaced by the response validator as "no schema defined for status code".

Error: no schema defined for status code '402' in the openapi spec (GET /v2/datasets/{datasetId}/items)
Files: apify-api/openapi/components/objects/datasets/dataset-items.yaml (sharedGet.responses)
Root cause: Every request passes through agentic-payment middleware and x402 payment-reuse checks, so a read on a storage endpoint can return 402 when a new payment hits a non-execution route or the account lacks usage/credit.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/agentic-payments/src/x402/x402_client.ts#L875

Error: no schema defined for status code '402' in the openapi spec (POST /v2/actor-tasks/{actorTaskId}/runs)
Files: apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@runs.yaml (post.responses)
Root cause: Task run creation goes through run-limit checks that throw notEnoughUsageToRunPaidActor / memory / concurrency errors with HTTP 402.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/actor-server/src/actor_jobs/run_limits_helper.ts#L194

Error: no schema defined for status code '402' in the openapi spec (GET & POST /v2/actor-tasks/{actorTaskId}/run-sync-get-dataset-items)
Files: apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync-get-dataset-items.yaml (get.responses, post.responses)
Root cause: Both variants launch a task run and hit the same run-limit checks that can return 402.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/actor-server/src/actor_jobs/run_limits_helper.ts#L194

Error: no schema defined for status code '401' in the openapi spec (POST /v2/actors/{actorId}/run-sync-get-dataset-items)
Files: apify-api/openapi/paths/actors/acts@{actorId}@run-sync-get-dataset-items.yaml (post.responses)
Root cause: The operation inherits global bearer/api-key security; an invalid token is rejected with 401 by the auth middleware. The GET sibling already documented 401, the POST did not.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/api/src/routes/routes_config.ts#L648

Error: no schema defined for status code '401' in the openapi spec (GET /v2/store)
Files: apify-api/openapi/paths/store/store.yaml (get.responses)
Root cause: The global auth middleware validates any supplied token before the route runs, so passing an invalid token to store search returns 401.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/api/src/middleware/authentication.ts#L91

Error: no schema defined for status code '401' in the openapi spec (GET /v2/actors/{actorId}/builds/default)
Files: apify-api/openapi/paths/actors/acts@{actorId}@builds@default.yaml (get.responses)
Root cause: Although the endpoint does not require a token (security: []), the auth middleware still validates any token that is supplied and returns 401 for an invalid one - the same reason the file already documents 403.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/api/src/routes/routes_config.ts#L521

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GyrB88NwS8d521dFAkwveu
Relax over-constrained response schemas that the validator flagged when the
live API returned null values or omitted optional fields.

Error: type.openapi.validation "must be number" at /response/data/options/maxTotalChargeUsd
Files: apify-api/openapi/components/schemas/actor-runs/RunOptions.yaml:30
Root cause: maxTotalChargeUsd is an optional run option, only stored when truthy, so runs created without it surface null. Made nullable to match the sibling maxItems field.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/schemas/src/actors.ts#L97

Error: minimum.openapi.validation "must be >= 1" at /response/data/options/maxItems
Files: apify-api/openapi/components/schemas/actor-runs/RunOptions.yaml:27
Root cause: The API defines maxItems with min 0 and treats 0 as a valid sentinel; the spec's minimum: 1 was stricter than the API. Lowered to 0.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/schemas/src/actors.ts#L94

Error: required.openapi.validation "must have required property 'deleteCount'" / 'listCount' at /response/data/stats
Files: apify-api/openapi/components/schemas/key-value-stores/KeyValueStoreStats.yaml:2
Root cause: The stats serializer picks only present fields and the DB marks every counter optional, so a pre-existing (get-or-create) store can omit deleteCount/listCount. Removed them from required.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/api/src/lib/key_value_stores.ts#L682

Error: required.openapi.validation "must have required property 'proxy'" at /response/data/proxy
Files: apify-api/openapi/components/schemas/users/UserPrivateInfo.yaml:4
Root cause: proxy is only attached when the user has proxy USE permission; otherwise the key is omitted. Removed from required.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/api/src/routes/users/user.ts#L84

Error: type.openapi.validation "must be string" at /response/data/requestUrl
Files: apify-api/openapi/components/schemas/webhooks/Webhook.yaml:48
Root cause: requestUrl is modeled as nullish and is only meaningful for HTTP-request webhooks; other action types return null. Made nullable.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/zod-types/src/common/webhooks.ts#L57

Error: required.openapi.validation "must have required property 'currentPricingInfo'" at /response/data/items/{i}/currentPricingInfo
Files: apify-api/openapi/components/schemas/store/StoreListActor.yaml:2
Root cause: The Recombee-backed store search maps items without a currentPricingInfo field, so it is not guaranteed. Removed from required.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/actor-server/src/recombee/recombee_store_search.ts#L183

Error: type.openapi.validation "must be string" at /response/data/items/{i}/notice (store) and /response/data/notice (actor)
Files: apify-api/openapi/components/schemas/store/StoreListActor.yaml:37, apify-api/openapi/components/schemas/actors/Actor.yaml:97
Root cause: notice is modeled as string | null in the data layer and coalesced to null when absent. Made nullable in both independent schemas.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/types/src/recombee.ts#L34

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GyrB88NwS8d521dFAkwveu
@apify-service-account

apify-service-account commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🗑️ Preview for this PR was deleted.

@apify-service-account

Copy link
Copy Markdown
Contributor

Important

Action required@Pijukatel please coordinate this docs PR with the Python API client PR linked below.

Because this PR modifies the OpenAPI specification, the generated models in apify-client-python must be regenerated to stay in sync. This has already been done automatically:

A companion PR has been opened in apify-client-python with the regenerated models: apify/apify-client-python#936

  • Please make sure to review and merge both PRs together to keep the OpenAPI spec and API clients in sync.
  • You can ask for review and help from the Tooling team if needed.

…02 payment reuse

Reusing an existing x402 agentic payment to read a run's results is allowed on
any storage route, so any storage GET (read) endpoint can return 402. Add 402 to
the shared GET response blocks of datasets, key-value stores, and request queues
(applied to the read variants only, not to writes).

Error: no schema defined for status code '402' in the openapi spec (storage read endpoints, e.g. GET /v2/datasets/{datasetId}/items)
Files: apify-api/openapi/components/objects/datasets/dataset.yaml (sharedGet), apify-api/openapi/components/objects/datasets/dataset-statistics.yaml (sharedGet), apify-api/openapi/components/objects/key-value-stores/key-value-store.yaml (sharedGet), apify-api/openapi/components/objects/key-value-stores/key-value-store-keys.yaml (sharedGet), apify-api/openapi/components/objects/key-value-stores/key-value-store-record.yaml (sharedGet), apify-api/openapi/components/objects/request-queues/request-queue.yaml (sharedGet), apify-api/openapi/components/objects/request-queues/request-queue-head.yaml (sharedGet), apify-api/openapi/components/objects/request-queues/request-queue-requests.yaml (sharedGet), apify-api/openapi/components/objects/request-queues/request-queue-request.yaml (sharedGet)
Root cause: A new x402 payment must be initiated on an Actor execution route, but reusing an already-initiated payment to read results is permitted on any route; when the reuse check fails on a non-execution (storage) route the API returns 402. The shared GET blocks also cover the default and last-run storage variants.
Reference: https://github.com/apify/apify-core/tree/abeddcb4b7b3dee66ea2169435153144dae91c19/src/packages/agentic-payments/src/x402/x402_client.ts#L873

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GyrB88NwS8d521dFAkwveu
@Pijukatel Pijukatel marked this pull request as ready for review July 10, 2026 08:36
@Pijukatel Pijukatel requested a review from vdusek July 10, 2026 08:36

@vdusek vdusek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@Pijukatel Pijukatel merged commit a911463 into master Jul 10, 2026
19 checks passed
@Pijukatel Pijukatel deleted the claude/openapi-errors-fix-or76l8 branch July 10, 2026 08:58
Pijukatel pushed a commit to apify/apify-client-python that referenced this pull request Jul 10, 2026
…tion (#936)

- Updates the auto-generated Pydantic models and TypedDicts based on the
proposed OpenAPI specification changes.
- Based on apify-docs PR
[#2754](apify/apify-docs#2754).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants