Skip to content

fix(openapi): Fix OpenAPI specification errors in /v2/actor-builds#2287

Open
Pijukatel wants to merge 2 commits intomasterfrom
fix/openapi/actor-builds
Open

fix(openapi): Fix OpenAPI specification errors in /v2/actor-builds#2287
Pijukatel wants to merge 2 commits intomasterfrom
fix/openapi/actor-builds

Conversation

@Pijukatel
Copy link
Contributor

@Pijukatel Pijukatel commented Feb 26, 2026

Summary

Fixes OpenAPI specification validation errors detected at runtime for the /v2/actor-builds endpoints.

Validation errors being fixed

These are lines from the error log generated by the unmerged validator running on integration tests https://github.com/apify/apify-core/pull/26052:

WARN  Response OpenAPI validation error {"url":"/v2/actor-builds/{id}","errors":[{"message":"no schema defined for status code '204' in the openapi spec","path":"/v2/actor-builds/{id}"}]}
WARN  Response OpenAPI validation error {"url":"/v2/actor-builds/{id}","errors":[{"message":"no schema defined for status code '404' in the openapi spec","path":"/v2/actor-builds/{id}"}]}
WARN  Response OpenAPI validation error {"url":"/v2/actor-builds/{id}/abort","errors":[{"message":"no schema defined for status code '403' in the openapi spec","path":"/v2/actor-builds/{id}/abort"}]}
WARN  Response OpenAPI validation error {"url":"/v2/actor-builds/{id}/abort","errors":[{"message":"no schema defined for status code '401' in the openapi spec","path":"/v2/actor-builds/{id}/abort"}]}
WARN  Response OpenAPI validation error {"url":"/v2/actor-builds/{id}","errors":[{"message":"no schema defined for status code '401' in the openapi spec","path":"/v2/actor-builds/{id}"}]}
WARN  Response OpenAPI validation error {"url":"/v2/actor-builds/{id}","errors":[{"message":"no schema defined for status code '403' in the openapi spec","path":"/v2/actor-builds/{id}"}]}
WARN  Response OpenAPI validation error {"url":"/v2/actor-builds/{id}/abort","errors":[{"message":"must be string,null","errorCode":"type.openapi.validation","path":"/response/data/finishedAt"}]}
WARN  Request OpenAPI validation error {"url":"/v2/actor-builds/{id}/log","errors":[{"message":"must have required property 'stream'","errorCode":"required.openapi.validation","path":"/query/stream"}]}
WARN  Request OpenAPI validation error {"url":"/v2/actor-builds/{id}/log","errors":[{"message":"must have required property 'stream'","errorCode":"required.openapi.validation","path":"/query/stream"}]}
WARN  Response OpenAPI validation error {"url":"/v2/actor-builds/{id}/log","errors":[{"message":"no schema defined for status code '404' in the openapi spec","path":"/v2/actor-builds/{id}/log"}]}
WARN  Response OpenAPI validation error {"url":"/v2/actor-builds/unexisting-build-id/openapi.json","errors":[{"message":"no schema defined for status code '404' in the openapi spec","path":"/v2/actor-builds/unexisting-build-id/openapi.json"}]}
WARN  Response OpenAPI validation error {"url":"/v2/actor-builds","errors":[{"message":"no schema defined for status code '403' in the openapi spec","path":"/v2/actor-builds"}]}

Changes

New file: components/responses/Forbidden.yaml

Added a shared 403 Forbidden response component, following the same pattern as the existing Unauthorized.yaml and NotFound.yaml components. Reused across all endpoints in this PR that can return 403.

paths/actor-builds/actor-builds.yaml - GET /v2/actor-builds

  • Added 403 response - returned when the caller lacks permission to list builds.

paths/actor-builds/actor-builds@{buildId}.yaml - GET and DELETE /v2/actor-builds/{buildId}

  • GET: Added 401 response - returned when no valid token is provided.
  • GET: Added 404 response - returned when the build ID does not exist.
  • DELETE: Added 404 response - returned when the build ID does not exist.

paths/actor-builds/actor-builds@{buildId}@abort.yaml - POST /v2/actor-builds/{buildId}/abort

  • Added 401 response - returned when no valid token is provided.
  • Added 403 response - returned when the caller does not own the build.

paths/actor-builds/actor-builds@{buildId}@log.yaml - GET /v2/actor-builds/{buildId}/log

  • Changed stream query parameter from required: true to required: false - it is an optional modifier, not required on every request.
  • Changed download query parameter from required: true to required: false - same reason.
  • Added 404 response - returned when the build ID does not exist.

paths/actor-builds/actor-builds@{buildId}@openapi.json.yaml - GET /v2/actor-builds/{buildId}/openapi.json

  • Added 404 response - returned when the build ID does not exist.

Issues

Partially implements: #2286

🤖 Generated with Claude Code


Note

Low Risk
Low risk: OpenAPI-spec-only changes that add missing error responses and relax query param requirements; no runtime logic is modified.

Overview
Fixes OpenAPI validation issues for /v2/actor-builds by adding missing response definitions and correcting parameter requirements.

Introduces a reusable 403 component (components/responses/Forbidden.yaml) and wires 401/403/404 responses into the relevant build endpoints (list, get, delete, abort, log, and openapi.json). Also makes stream and download query params optional on the build log endpoint to match actual usage.

Written by Cursor Bugbot for commit dd5b774. Configure here.

@github-actions github-actions bot added this to the 135th sprint - Tooling team milestone Feb 26, 2026
@github-actions github-actions bot added the t-tooling Issues with this label are in the ownership of the tooling team. label Feb 26, 2026
@apify-service-account
Copy link

Preview for this PR was built for commit b44c9d3 and is ready at https://pr-2287.preview.docs.apify.com!

@apify-service-account
Copy link

Preview for this PR was built for commit dd5b7749 and is ready at https://pr-2287.preview.docs.apify.com!

@Pijukatel Pijukatel changed the title fix: add missing response codes and fix schema issues in actor-builds endpoints fix(openapi): add missing response codes and fix schema issues in actor-builds endpoints Feb 27, 2026
@Pijukatel Pijukatel requested review from vdusek February 27, 2026 10:03
@Pijukatel Pijukatel changed the title fix(openapi): add missing response codes and fix schema issues in actor-builds endpoints fix(openapi): Fix OpenAPI specification errors in /v2/actor-builds Feb 27, 2026
@Pijukatel Pijukatel changed the title fix(openapi): Fix OpenAPI specification errors in /v2/actor-builds fix(openapi): Fix OpenAPI specification errors in /v2/actor-builds Feb 27, 2026
Copy link
Contributor

@vdusek vdusek left a comment

Choose a reason for hiding this comment

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

lgtm

@Pijukatel Pijukatel marked this pull request as ready for review February 27, 2026 11:23
Copy link
Member

@fnesveda fnesveda left a comment

Choose a reason for hiding this comment

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

The changes themselves look good, so approving.

I also had a thought about this process in general. If I understand it correctly, you've written an API middleware to check whether the requests sent to and responses returned from the API match its OpenAPI schema, and then you've ran the integration tests to generate some API requests to find the places where it doesn't match?

I think almost all of our endpoints can return any of 400, 401, 403 and 404 statuses, however, for some of the endpoints changed here, I see that you didn't need to add those errors to the endpoints' response schema. This leads me to think that we have a gap in our integration tests, which don't cover all of the possible situations, and don't generate all of the errors that can happen during real usage.

This initiative gives us a good opportunity to discover what those gaps are. Basically:

  1. We fix the OpenAPI schema to be correct for how our API behaves during integration tests
  2. We turn on the API middleware in production, and see what errors does it produce. Those errors then point us to behaviors we don't have covered by integration tests.
  3. We add integration tests for these behaviors (if it makes sense).

CC @tobice what do you think? I think it's a good chance to discover some gaps in our testing coverage.

@Pijukatel
Copy link
Contributor Author

...If I understand it correctly, you've written an API middleware to check whether the requests sent to and responses returned from the API match its OpenAPI schema, and then you've ran the integration tests to generate some API requests to find the places where it doesn't match?...

Exactly. It will be an iterative process. So the fixes in the upcoming PRs are not complete, but incremental, based on the feedback from the validator only.

There is one point I am a little unsure about. I work with the assumption that the actual implementation is correct and the specification is not, which will be a good assumption in the majority of cases, but there is a risk that such approach could also propagate some bad implementation to the specification.

@fnesveda
Copy link
Member

...If I understand it correctly, you've written an API middleware to check whether the requests sent to and responses returned from the API match its OpenAPI schema, and then you've ran the integration tests to generate some API requests to find the places where it doesn't match?...

Exactly. It will be an iterative process. So the fixes in the upcoming PRs are not complete, but incremental, based on the feedback from the validator only.

Thanks 👍

There is one point I am a little unsure about. I work with the assumption that the actual implementation is correct and the specification is not, which will be a good assumption in the majority of cases, but there is a risk that such approach could also propagate some bad implementation to the specification.

I don't think there's much we can do about that except manually report whenever a change to the spec feels wrong.

@janbuchar
Copy link
Contributor

2. We turn on the API middleware in production, and see what errors does it produce. Those errors then point us to behaviors we don't have covered by integration tests.

3. We add integration tests for these behaviors (if it makes sense).

CC @tobice what do you think? I think it's a good chance to discover some gaps in our testing coverage.

If the middleware doesn't tank performance too much, then yes, the endgame is to turn it on in production.

@tobice
Copy link
Contributor

tobice commented Feb 27, 2026

Using the schema to check what's missing in the integration tests makes sense to me, although I wouldn't treat it as a top priority right now. Also, we are not always consistent with the error codes... especially with 403 vs 404, which is a known issue.

Anyway, I can file a ticket for this and add it to our backlog.

Then for anything weird you find in there, feel free to file an issue in apify-core with t-core-services label.

And btw thanks a lot for this! ❤️ I know this should be our job 🙈

@fnesveda
Copy link
Member

If the middleware doesn't tank performance too much, then yes, the endgame is to turn it on in production.

If it would, we could turn it on only for a small percentage of requests. It would take longer to gather all the errors, but it could still work.

@janbuchar
Copy link
Contributor

If the middleware doesn't tank performance too much, then yes, the endgame is to turn it on in production.

If it would, we could turn it on only for a small percentage of requests. It would take longer to gather all the errors, but it could still work.

I was thinking the same. The only issue I can think of that after some time, errors will be most likely to appear in seldom-called endpoints. I guess we could adjust for that in the sampling algorithm.

@Pijukatel
Copy link
Contributor Author

Pijukatel commented Feb 27, 2026

I was thinking the same. ...

And so did I :-)
The current implementation comes with one argument, validationFraction. For integration tests, I set it to 1 (100%), but for production, I would turn it down initially.

        this.app.use(openApiRequestValidationMiddleware({ validationFraction: 1 }));
        this.app.use(openApiResponseValidationMiddleware({ validationFraction: 1 }));

If `true` or `1` then the logs will be streamed as long as the run or
build is running.
required: true
required: false
Copy link
Contributor

Choose a reason for hiding this comment

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

isn't required: false the default option? not a request

@Pijukatel
Copy link
Contributor Author

I will gradually write all the stuff I am not sure about here:
https://github.com/apify/apify-core/issues/26103

Once there is enough open questions there, I will invite @tobice to review it. (Not all will be issues, some will be just my lack of understanding of the API)

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.

6 participants