Skip to content

Fix recursive gRPC collection generation - #3990

Merged
raphael merged 1 commit into
v3from
fix/recursive-grpc-collections
Sep 16, 2026
Merged

raphael merged 1 commit into
v3from
fix/recursive-grpc-collections

Conversation

@raphael

@raphael raphael commented Sep 16, 2026

Copy link
Copy Markdown
Member

Fixes #2515.

goa gen could overflow the stack or keep expanding code for a gRPC result whose children contain the same result type, such as CategoryResult with ArrayOf("CategoryResult"). The same problem affects recursive maps. These designs now generate finite conversion functions, and the generated clients and servers can convert finite nested values in both directions.

Three generator responsibilities are involved:

  • Validation discovery now tracks named types regardless of whether they are reached through an object field, array, map, or union. It still examines constraints after a recursive field.
  • gRPC array and map conversions call planned private helpers for named object elements. Recursive calls reuse the active helper instead of expanding the same object inline. Primitive aliases and collection wrappers keep their existing conversion paths.
  • The shared helper registry follows the exact wrapper fields recorded during planning at every nested collection location. It compares the actual generated parameter and result types before sharing a function. Existing root attribute replacement by custom hooks is preserved.

All nine changed golden files were reviewed. The changes replace inline object element conversions with private helper calls; complete-file goldens include the extracted bodies. Public constructor signatures, protobuf schemas, scalar conversions, presence checks, and validation rules remain unchanged. The union test now inspects helper bodies as well as the outer conversion, since the union switch can move into an element helper.

Validation: GOTOOLCHAIN=go1.25.14 make all (lint, the complete test suite, and JSON-RPC integration tests). New generated-module tests compile every package, exercise the original recursive result through response encoding/decoding and protobuf serialization, round-trip recursive arrays, maps, nested collections, and mutually recursive types through all four client/server conversions, reject invalid grandchildren, and check optional zero values and defaults. A separate helper-registry test checks sharing through several nested wrappers in either direction.

Regenerate with a Goa version containing this fix. No DSL changes, wire migration, coordinated deployment, or new runtime configuration are required; existing generated programs do not change until regenerated. Reverting generated source restores prior behavior for previously working designs. Reverting the generator prevents the affected recursive designs from generating again. No exported Go API changes are introduced.

@raphael
raphael merged commit 18074ff into v3 Sep 16, 2026
5 checks passed
@raphael
raphael deleted the fix/recursive-grpc-collections branch September 16, 2026 14:46
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.

Infinite recursion when Type used in GRPC has an ArrayOf cyclic attribute

1 participant