Skip to content

Comments

fix: support non-indexed deepObject array unmarshaling (#22)#96

Open
mromaszewicz wants to merge 1 commit intooapi-codegen:mainfrom
mromaszewicz:fix/22
Open

fix: support non-indexed deepObject array unmarshaling (#22)#96
mromaszewicz wants to merge 1 commit intooapi-codegen:mainfrom
mromaszewicz:fix/22

Conversation

@mromaszewicz
Copy link
Member

OpenAPI 3.0's deepObject style has undefined behavior for arrays. Two conventions exist in the wild:

  • Indexed: p[vals][0]=a&p[vals][1]=b (oapi-codegen's current format)
  • Non-indexed: p[vals]=a&p[vals]=b (Swagger UI / Rails convention)

Swagger UI generates the non-indexed format, which previously failed with "[field] has multiple values". This change makes UnmarshalDeepObject accept both formats by detecting repeated query parameter keys and expanding them into synthetic indexed entries (e.g. [vals][0], [vals][1]) before feeding them into the existing tree-construction and assignment logic.

Marshaling (MarshalDeepObject) intentionally remains unchanged and continues to emit the indexed format. The indexed format is unambiguous, already consumed correctly by all known implementations, and is what oapi-codegen's own generated clients expect. Changing it to the non-indexed format would be a breaking change for consumers that rely on the current wire format, with no practical benefit since both formats are now accepted on the unmarshaling side.

@mromaszewicz mromaszewicz requested a review from a team as a code owner February 24, 2026 07:52
OpenAPI 3.0's deepObject style has undefined behavior for arrays.
Two conventions exist in the wild:

- Indexed: p[vals][0]=a&p[vals][1]=b (oapi-codegen's current format)
- Non-indexed: p[vals]=a&p[vals]=b (Swagger UI / Rails convention)

Swagger UI generates the non-indexed format, which previously failed
with "[field] has multiple values". This change makes UnmarshalDeepObject
accept both formats by detecting repeated query parameter keys and
expanding them into synthetic indexed entries (e.g. [vals][0], [vals][1])
before feeding them into the existing tree-construction and assignment
logic.

Marshaling (MarshalDeepObject) intentionally remains unchanged and
continues to emit the indexed format. The indexed format is
unambiguous, already consumed correctly by all known implementations,
and is what oapi-codegen's own generated clients expect. Changing it
to the non-indexed format would be a breaking change for consumers
that rely on the current wire format, with no practical benefit since
both formats are now accepted on the unmarshaling side.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

1 participant