Skip to content

fix(schema): keep oneof validation out of rendered variants - #280

Merged
sudorandom merged 1 commit into
sudorandom:mainfrom
bastionplatforms:fix/oneof-rendering-variants
Sep 11, 2026
Merged

sudorandom merged 1 commit into
sudorandom:mainfrom
bastionplatforms:fix/oneof-rendering-variants

Conversation

@jalaziz

@jalaziz jalaziz commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

This fixes a an issue introduced in #264.

While that PR introduced a fix to match protobuf's expected oneof at-most-once behavior, it did so by introducing an extra, untitled branch that resulted in a phantom variant in documentation renderers (e.g. Mintlify).

An alternative way of expressing the same rule is to have a sibling not rule which is seemingly ignored by doc renderers.

Additionally, the member properties now stay at the root of the message schema, which leaves nothing to merge into allOf and nothing for the request body to recover from there, so both are gone.

A protobuf oneof permits at most one member, and documentation renderers
display every oneOf and anyOf branch as a variant. Encoding the at-most-one
guard as one of those branches renders an untitled, propertyless option
beside the real fields.

Render the members as an anyOf of titled field schemas and assert
at-most-one under not, which no renderer reads as a list of variants. The
assertion holds when some member is set but not exactly one, so it stays
proportional to the number of members.

The member properties stay at the root of the message schema, which leaves
nothing to merge into allOf and nothing for the request body to recover
from there, so both are gone.

(buf.validate.oneof).required still layers exactly-one as a sibling allOf.
@sudorandom

Copy link
Copy Markdown
Owner

Thanks for this! Mapping protobuf oneOf to OpenAPI has continuously been more complex than expected. This implementation checks out

@sudorandom
sudorandom merged commit 393ec8c into sudorandom:main Sep 11, 2026
4 checks passed
sudorandom added a commit that referenced this pull request Sep 11, 2026
The oneof encoding introduced in #280 composes per-container at-most-one
constraints as separate allOf branches, but no fixture exercised more than
one real oneof container in a single message. Add a two-container message
with request-validation cases asserting each container's exclusivity
applies independently: one member from each container is valid, two
members of the same container are not.
@jalaziz
jalaziz deleted the fix/oneof-rendering-variants branch September 11, 2026 08:48
@jalaziz

jalaziz commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

most welcome! Honestly, mapping proto to OpenAPI in general is a pain, but thank you for maintaining this project!

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.

2 participants