Skip to content

OneOf Type in Streaming Payload Generates Invalid Code #3869

@RedMarcher

Description

@RedMarcher

When using a OneOf type within a Payload for a gRPC streaming method (StreamingPayload/StreamingResult), Goa attempts to map the Payload fields to gRPC metadata (headers). However, for OneOf types, the generated decoding logic is incomplete/invalid, resulting in compilation errors.

Steps to Reproduce

1. Define a OneOf Type

var VersionRef = Type("VersionRef", func() {
    Description("Reference to a version - either by UUID or by branch/tag name.")
    OneOf("ref_type", func() {
        Field(1, "version_id", String, "UUID of the specific version", func() {
            Format(FormatUUID)
        })
        Field(2, "ref_name", String, "Name of a branch or tag.")
    })
    Required("ref_type")
})

2. Use it in a Streaming Method Payload

Method("downloadVersion", func() {
    // ...
    Payload(func() {
        // ...
        Field(3, "version_ref", VersionRef, "Version reference")
        // ...
    })
    StreamingResult(VersionStreamPayload)
    GRPC(func() {
        Response(CodeOK)
    })
})

3. Run goa gen
Resulting Error
The generated file
gen/grpc/repository/server/encode_decode.go
contains invalid Go code in DecodeDownloadVersionRequest.

Compiler Output:

gen/grpc/repository/server/encode_decode.go:464:4: declared and not used: versionRefRaw
gen/grpc/repository/server/encode_decode.go:472:9: undefined: VersionRef_VersionID
gen/grpc/repository/server/encode_decode.go:475:9: undefined: VersionRef_RefName
gen/grpc/repository/server/types.go:240:17: cannot use versionRef (variable of type struct{RefType interface{refTypeVal()}}) as *repository.VersionRef value in assignment

Generated Code Snippet
The generator leaves a comment seemingly, but it does not block compilation nor return an error.

// gen/grpc/repository/server/encode_decode.go
if vals := md.Get("version_ref"); len(vals) == 0 {
    err = goa.MergeErrors(err, goa.MissingFieldError("version_ref", "metadata"))
} else {
    versionRefRaw := vals[0]
    // unsupported type VersionRef for var versionRef  <-- GENERATED COMMENT
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions