Skip to content

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

Merged
Pijukatel merged 1 commit into
masterfrom
claude/openapi-validation-errors-bw6ho0
Jul 2, 2026
Merged

docs(openapi): Autofix OpenAPI spec validation errors#2719
Pijukatel merged 1 commit into
masterfrom
claude/openapi-validation-errors-bw6ho0

Conversation

@Pijukatel

@Pijukatel Pijukatel commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Auto-generated OpenAPI fixes suggestions based on validation errors reported by the OpenAPI validator running in staging apify-api.

apify-core version: https://github.com/apify/apify-core/tree/097f5cbed085ef8a99640a1004531b325b5c03f3

Detailed changes description

Error fixes

Nullable user profile fields

  • Files: apify-api/openapi/components/schemas/users/Profile.yaml:4-23
  • Error: Response OpenAPI validation error {"errors":[{"errorCode":"type.openapi.validation","message":"must be string","path":"/response/data/profile/bio"},{"errorCode":"type.openapi.validation","message":"must be string","path":"/response/data/profile/githubUsername"}],"method":"GET","statusCode":200,"url":"/v2/users/{userId}"} - also raised for /profile/twitterUsername, /profile/websiteUrl and /profile/pictureUrl, on both GET /v2/users/{userId} and GET /v2/users/me (~340 occurrences, ongoing through the end of the log window).
  • Root cause: All profile fields are optional and a field cleared by the user is stored as null. getProfileOfUser() copies the stored profile values into the API response unchanged, so the API returns bio: null, githubUsername: null, etc., while the spec declared these five fields as non-nullable string. Changed them to type: [string, "null"].
  • Reference: https://github.com/apify/apify-core/blob/097f5cbed085ef8a99640a1004531b325b5c03f3/src/packages/users-server/src/profiles.ts#L34-L49

Webhook test dispatch eventData without actorRunId

  • Files: apify-api/openapi/components/schemas/webhook-dispatches/WebhookDispatch.yaml:28-46
  • Error: Response OpenAPI validation error {"errors":[{"errorCode":"required.openapi.validation","message":"must have required property 'actorRunId'","path":"/response/data/eventData/actorRunId"}],"method":"POST","statusCode":201,"url":"/v2/webhooks/{webhookId}/test?token=[REDACTED]"}
  • Root cause: When a webhook is tested against a build resource, processActorJobForWebhook() produces eventData = { actorId, actorBuildId } - there is no actorRunId for build events. The eventData schema required both actorId and actorRunId and did not declare actorBuildId or actorTaskId at all (the run case produces { actorId, actorTaskId, actorRunId }). Removed actorRunId from required (keeping actorId, which is present in both cases) and added the missing actorBuildId and actorTaskId properties.
  • Reference: https://github.com/apify/apify-core/blob/097f5cbed085ef8a99640a1004531b325b5c03f3/src/packages/actor-server/src/actor_commons.ts#L246-L266

Nullable imageSizeBytes in build stats

  • Files: apify-api/openapi/components/schemas/actor-builds/BuildStats.yaml:15-16
  • Error: Response OpenAPI validation error {"errors":[{"errorCode":"type.openapi.validation","message":"must be integer","path":"/response/data/stats/imageSizeBytes"},{"errorCode":"type.openapi.validation","message":"must be null","path":"/response/data/stats"},{"errorCode":"anyOf.openapi.validation","message":"must match a schema in anyOf","path":"/response/data/stats"}],"method":"POST","statusCode":200,"url":"/v2/actor-builds/{buildId}/abort"}
  • Root cause: Verified by live reproduction against production. Build stats have two writers: the finish path persists the worker's payload verbatim with imageSizeBytes: null (finishActJob / updateActorJobRecordOnFinish do $set: { ...payload, finishedAt } with no post-processing), and actor-build-analyzer overwrites it with the real integer computed from dockerImageHistory roughly 45 seconds later. Any read of the build in that window - in the logged case an abort that raced the build's completion within the same second (finishedAt 08:57:22.145Z, abort logged 08:57:22) and was served the just-finished document by the if (actorJob.finishedAt) return actorJob short-circuit - returns "stats": { ..., "imageSizeBytes": null }. Against type: integer the null produces exactly the three logged errors: must be integer on the field, plus must be null and must match a schema in anyOf on the parent stats (which validates as anyOf [BuildStats, null], and both branches fail). Reproduced end-to-end: a fresh build served {"durationMillis": 1000, "runTimeSecs": 1, "computeUnits": 0.0011..., "imageSizeBytes": null} from build success until the analyzer update replaced null with 531356672 at t+47s. Changed imageSizeBytes to type: [integer, "null"].
  • Reference: https://github.com/apify/apify-core/blob/097f5cbed085ef8a99640a1004531b325b5c03f3/src/packages/actor-server/src/actor_commons.ts#L375-L400

Missing full-permission-actor-blocked-for-admin in ErrorType enum

  • Files: apify-api/openapi/components/schemas/common/ErrorType.yaml:129
  • Error: Response OpenAPI validation error {"errors":[{"errorCode":"enum.openapi.validation","message":"must be equal to one of the allowed values: 3d-secure-auth-failed, access-right-already-exists, action-not-foun...[truncated]","path":"/response/error/type"}],"method":"POST","statusCode":403,"url":"/v2/actors/{actorId}/runs"}
  • Root cause: The returned error/type value is not visible because the log line is truncated, so it was identified by exclusion: diffing all error types defined in apify-core (newMeteorishError calls in src/packages/errors) against the spec enum, the only type with status 403 that is thrown in the public run-start path (validateUserCanRunActor) and missing from the enum is full-permission-actor-blocked-for-admin, thrown when an admin account starts a full-permission Actor not managed by Apify. Added it to the enum.
  • Reference: https://github.com/apify/apify-core/blob/097f5cbed085ef8a99640a1004531b325b5c03f3/src/packages/actor-server/src/actor_jobs/actor_jobs.server.ts#L793-L803

Missing 413 and 415 responses on dataset items POST endpoints

  • Files: apify-api/openapi/components/objects/datasets/dataset-items.yaml:431-434
  • Error: Response OpenAPI validation error {"errors":[{"message":"no schema defined for status code '415' in the openapi spec","path":"/v2/datasets/{datasetId}/items?token=[REDACTED]"}],"method":"POST","statusCode":415,"url":"/v2/datasets/{datasetId}/items?token=[REDACTED]"}
  • Root cause: The API returns 415 unsupported-content-encoding when the express body-parser rejects the request's Content-Encoding (encoding.unsupported is transformed in the API error middleware), but the shared POST items definition declared no 415 response. Added 413 and 415 responses (both required for endpoints with requestBody by this repo's error-response guidelines) referencing the existing shared PayloadTooLarge.yaml and UnsupportedMediaType.yaml components. The shared sharedPost anchor propagates the fix to all four push-items operations (dataset_items_post, default/last-run/task-last-run variants).
  • Reference: https://github.com/apify/apify-core/blob/097f5cbed085ef8a99640a1004531b325b5c03f3/src/api/src/middleware/error_transformer.ts#L27-L30

Issues

@apify-service-account

apify-service-account commented Jul 2, 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#917

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

Comment thread apify-api/openapi/components/schemas/actor-builds/BuildStats.yaml Outdated
Comment thread apify-api/openapi/components/schemas/actor-builds/BuildStats.yaml Outdated
Fixes for response OpenAPI validation errors observed in production
apify-api logs (Jul 1-2), deduplicated to five root causes:

- Profile.yaml: bio, pictureUrl, githubUsername, websiteUrl and
  twitterUsername can be null (GET /v2/users/me, GET /v2/users/{userId})
- WebhookDispatch.yaml: eventData for build events contains only actorId
  and actorBuildId, so actorRunId is no longer required; added
  actorBuildId and actorTaskId properties (POST /v2/webhooks/{webhookId}/test)
- BuildStats.yaml: imageSizeBytes is null in the window between the
  build finishing and actor-build-analyzer writing the real value,
  verified by live reproduction (POST /v2/actor-builds/{buildId}/abort)
- ErrorType.yaml: added full-permission-actor-blocked-for-admin, thrown
  with 403 when starting a run (POST /v2/actors/{actorId}/runs)
- dataset-items.yaml: added 413 and 415 error responses to the shared
  POST items definition (POST /v2/datasets/{datasetId}/items)

Co-Authored-By: Claude <noreply@anthropic.com>
@Pijukatel Pijukatel force-pushed the claude/openapi-validation-errors-bw6ho0 branch from 8859767 to 96dcb07 Compare July 2, 2026 12:57
@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:

The companion apify-client-python PR has been updated with the latest spec changes: apify/apify-client-python#917

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

@Pijukatel Pijukatel merged commit 19d2eec into master Jul 2, 2026
19 checks passed
@Pijukatel Pijukatel deleted the claude/openapi-validation-errors-bw6ho0 branch July 2, 2026 13:19
Pijukatel pushed a commit to apify/apify-client-python that referenced this pull request Jul 2, 2026
- Updates the auto-generated Pydantic models and TypedDicts based on the
proposed OpenAPI specification changes.
- Based on apify-docs PR
[#2719](apify/apify-docs#2719).
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.

5 participants