Skip to content

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

Draft
Pijukatel wants to merge 3 commits into
masterfrom
claude/amazing-davinci-i4qm1x
Draft

docs(openapi): Autofix OpenAPI spec validation errors#2670
Pijukatel wants to merge 3 commits into
masterfrom
claude/amazing-davinci-i4qm1x

Conversation

@Pijukatel

@Pijukatel Pijukatel commented Jun 22, 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: https://apify-pr-test-env-logs.s3.us-east-1.amazonaws.com/apify/apify-core/27741/api-80c58e9c104959349635419c82b6e5174b16ded3.html

apify-core version: https://github.com/apify/apify-core/commit/6f157da99ca076e5f3f1da67f507e885d6aeafe8

Stop reason: No new fixes possible. Three genuine spec/API mismatches were fixed; every other validation error in the log is a known validator false positive, an intentional negative test, or an out-of-scope artifact (all documented below).

Detailed changes description

Error fixes

Add service-worker-registration-not-allowed to the ErrorType enum

  • Files: apify-api/openapi/components/schemas/common/ErrorType.yaml:311
  • Error: Response OpenAPI validation error {"url":"/v2/key-value-stores/{storeId}/records/sw.js","method":"GET","statusCode":403,"errors":[{"message":"must be equal to one of the allowed values: 3d-secure-auth-failed, access-right-already-exists, ... [truncated]","errorCode":"enum.openapi.validation","path":"/response/error/type"}]}
  • Root cause: Fetching a key-value store record with a service-worker request header is blocked with HTTP 403 and the error type service-worker-registration-not-allowed. That value was missing from the ErrorType enum, so the validator rejected the (correct) error response body. An integration test asserts this exact error type (tests/integration/tests/key_value_stores/key_value_store.record.js).
  • Reference: https://github.com/apify/apify-core/tree/6f157da99ca076e5f3f1da67f507e885d6aeafe8/src/packages/errors/src/errors/api.ts#L158

Document the status query parameter on the last-run log endpoints

  • Files: apify-api/openapi/components/objects/logs/log.yaml:103, apify-api/openapi/components/objects/logs/log.yaml:120
  • Error: Request OpenAPI validation error {"url":"/v2/actor-tasks/{actorTaskId}/runs/last/log?status=SUCCEEDED","method":"GET","errors":[{"path":"/query/status","message":"Unknown query parameter 'status'"}]}
  • Root cause: Every /runs/last* route (including /runs/last/log) is served by lastRunRouter, which reads and validates the status query parameter and uses it to select the last run before its log is returned. The getLastRun and getTaskLastRun operations did not declare status, so valid requests using it were rejected. The base runs/last endpoint already documents the same statusLastRun parameter.
  • Reference: https://github.com/apify/apify-core/tree/6f157da99ca076e5f3f1da67f507e885d6aeafe8/src/api/src/routes/actors/last_run.ts#L21

Do not require id in the request-queue update request body

  • Files: apify-api/openapi/components/schemas/request-queues/Request.yaml:5
  • Error: Request OpenAPI validation error {"url":"/v2/actor-runs/{runId}/request-queue/requests/{requestId}?token=[REDACTED]","method":"PUT","errors":[{"message":"must have required property 'id'","errorCode":"required.openapi.validation","path":"/body/id"}]}
  • Root cause: The update-request handler deletes id from the request body ("it's computed from uniqueKey always") and validates the body against a schema that requires only uniqueKey and url. The shared Request schema used for the PUT body wrongly required id, rejecting valid update requests that omit it (the failing request supplied uniqueKey and url).
  • Reference: https://github.com/apify/apify-core/tree/6f157da99ca076e5f3f1da67f507e885d6aeafe8/src/api/src/routes/request_queues/request.ts#L189

Refactoring

None.

Unfixed errors

False positives

Nullable date-time fields rejected as "must be string,null"

  • Error: Response OpenAPI validation error {"url":"/v2/actors/{actorId}","method":"GET","statusCode":200,"errors":[{"message":"must be string,null","errorCode":"type.openapi.validation","path":"/response/data/taggedBuilds/{tag}/finishedAt"}]} — and equivalently finishedAt on POST /v2/actor-builds/{buildId}/abort, startedAt/finishedAt on GET /v2/webhook-dispatches/{dispatchId} calls, and nextRunAt/lastRunAt on schedules.
  • Root cause: The validator incorrectly raises a type error when a type: [string, "null"] + format: date-time field holds null. These fields are legitimately nullable in apify-core (an unfinished build/run has finishedAt = null, a schedule may have nextRunAt = null). This is the documented validator false positive; the schemas are correct and are left unchanged.
  • Reference: https://github.com/apify/apify-core/tree/6f157da99ca076e5f3f1da67f507e885d6aeafe8/src/packages/types/src/schedules.ts#L80

taggedBuilds anyOf reported as "must be null" / "must match a schema in anyOf"

  • Error: Response OpenAPI validation error {"url":"/v2/actors/{actorId}","method":"GET","statusCode":200,"errors":[{"message":"must match a schema in anyOf","errorCode":"anyOf.openapi.validation","path":"/response/data/taggedBuilds/{tag}"}]}
  • Root cause: Cascade of the nullable date-time false positive above. taggedBuilds (and each tagged build) is modelled as anyOf: [object, null], and each ActorTaggedBuild contains a nullable finishedAt. When the validator wrongly rejects finishedAt: null, the object branch fails, the null branch is then tried, and the whole anyOf is reported as failing. The schema is correct.
  • Reference: https://github.com/apify/apify-core/tree/6f157da99ca076e5f3f1da67f507e885d6aeafe8/src/packages/types/src/actor.ts#L783

Out of scope errors

Intentional negative tests (deliberately malformed requests)

  • Error: representative cases — /body/generalAccess must be string / invalid enum (tests send 'invalid', 0, null); /body/eventTypes/{i} enum (MISSED_EVENT_TYPE); /body/handledAt must match format "date-time" ('not-a-date'); /body/options/timeoutSecs must be integer,null ('bbb'); /query/filter/{i} enum (filter=pending,invalid); missing required actId on POST /v2/actor-tasks; missing required targetActorId on metamorph; 415 media-type tests for POST /v2/actors and POST /v2/tools/encode-and-sign; dataset items must be object (item-validation path).
  • Root cause: These requests are deliberately malformed by the integration tests to verify the API rejects them, and the tests assert that rejection. The spec already documents the correct contract, so these are not spec defects and must not be changed.

Test-harness, method and meta-endpoint artifacts

  • Error: Unknown query parameter 'method' (e.g. ?method=PoSt, ?method=XXX); OPTIONS/XXX method not allowed; GET /v2/openapi.json not found; GET /v2/actors/{actorId}/oauth-connections not found.
  • Root cause: These originate from the test harness's method-override query parameter and CORS/invalid-method probes, plus internal/meta endpoints that are intentionally not part of the public OpenAPI document. They are not response-schema defects and are out of scope for this autofix pass.

Issues

Partially implements: #2286

claude added 3 commits June 22, 2026 12:41
…e enum

Error: Response OpenAPI validation error {"url":"/v2/key-value-stores/{storeId}/records/sw.js","method":"GET","statusCode":403,"errors":[{"message":"must be equal to one of the allowed values: 3d-secure-auth-failed, access-right-already-exists, ... [truncated]","errorCode":"enum.openapi.validation","path":"/response/error/type"}]}
Files: apify-api/openapi/components/schemas/common/ErrorType.yaml:311
Root cause: Fetching a key-value store record with a service-worker header is rejected with HTTP 403 and error type "service-worker-registration-not-allowed", but that value was missing from the ErrorType enum, so the validator failed the response body.
Reference: https://github.com/apify/apify-core/tree/6f157da99ca076e5f3f1da67f507e885d6aeafe8/src/packages/errors/src/errors/api.ts#L158
Error: Request OpenAPI validation error {"url":"/v2/actor-tasks/{actorTaskId}/runs/last/log?status=SUCCEEDED","method":"GET","errors":[{"path":"/query/status","message":"Unknown query parameter 'status'"}]}
Files: apify-api/openapi/components/objects/logs/log.yaml:103, apify-api/openapi/components/objects/logs/log.yaml:120
Root cause: The runs/last/log endpoints (for both actors and actor tasks) resolve the last run filtered by the status query parameter and then return its log, but the getLastRun and getTaskLastRun operations did not declare the status parameter, so valid requests using it were rejected by the validator.
Reference: https://github.com/apify/apify-core/tree/6f157da99ca076e5f3f1da67f507e885d6aeafe8/src/api/src/routes/actors/last_run.ts#L21
Error: Request OpenAPI validation error {"url":"/v2/actor-runs/{runId}/request-queue/requests/{requestId}?token=[REDACTED]","method":"PUT","errors":[{"message":"must have required property 'id'","errorCode":"required.openapi.validation","path":"/body/id"}]}
Files: apify-api/openapi/components/schemas/request-queues/Request.yaml:5
Root cause: The update-request handler deletes id from the request body ("it's computed from uniqueKey always") and validates the body against a schema that requires only uniqueKey and url. The Request schema used for the PUT body incorrectly required id, rejecting valid update requests that omit it.
Reference: https://github.com/apify/apify-core/tree/6f157da99ca076e5f3f1da67f507e885d6aeafe8/src/api/src/routes/request_queues/request.ts#L189
@github-actions github-actions Bot added this to the 143rd sprint - Tooling team milestone Jun 22, 2026
@github-actions github-actions Bot added the t-tooling Issues with this label are in the ownership of the tooling team. label Jun 22, 2026
@apify-service-account

apify-service-account commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

✅ Preview for this PR (commit c7e8ad1) is ready at https://pr-2670.preview.docs.apify.com (see action run).

@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#874

  • 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-tooling Issues with this label are in the ownership of the tooling team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants