Skip to content

InstancePrototype oneOf Constraint Validation Failure #133

@pfeifferj

Description

@pfeifferj

When creating VPC instances using InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment in vpc-go-sdk v0.74.0 and v0.74.1, the VPC API returns the error:

Expected only one oneOf fields to be set: got 0

This error occurs even when all required fields are properly set in the Go struct. The issue appears to be related to JSON marshaling of interface-typed fields.

Environment

  • SDK Version: github.com/IBM/vpc-go-sdk v0.74.1 (also occurs in v0.74.0)
  • Go Version: 1.24.6
  • API Version: 2025-09-30
  • Region: eu-de

Expected Behavior

Creating a VPC instance with the following code should succeed:

imageID := "r010-17a6c2b3-c93b-4018-87ca-f078ef21e02b"
zoneName := "eu-de-2"
profileName := "bx2-2x8"
vpcID := "r010-vpc-id"
subnetID := "subnet-id"

primaryNetworkAttachment := &vpcv1.InstanceNetworkAttachmentPrototype{
    VirtualNetworkInterface: &vpcv1.InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeInstanceNetworkAttachmentContext{
        Subnet: &vpcv1.SubnetIdentityByID{ID: &subnetID},
    },
}

instancePrototype := &vpcv1.InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment{
    Image: &vpcv1.ImageIdentityByID{ID: &imageID},
    Zone: &vpcv1.ZoneIdentityByName{Name: &zoneName},
    Profile: &vpcv1.InstanceProfileIdentityByName{Name: &profileName},
    VPC: &vpcv1.VPCIdentityByID{ID: &vpcID},
    Name: &instanceName,
    PrimaryNetworkAttachment: primaryNetworkAttachment,
}

result, response, err := vpcService.CreateInstance(&vpcv1.CreateInstanceOptions{
    InstancePrototype: instancePrototype,
})

Actual Behavior

The VPC API returns an error:

Expected only one oneOf fields to be set: got 0

Analysis

The issue appears to be in how the SDK marshals interface-typed fields to JSON. When examining the struct before the API call, all fields are non-nil. However, when the struct is marshaled to JSON (which the HTTP client does before sending the request), interface fields are not being properly serialized.

Evidence

I created a unit test that demonstrates the marshaling issue:

// Create instance prototype with all fields set
instancePrototype := &vpcv1.InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment{
    Image: &vpcv1.ImageIdentityByID{ID: &imageID},
    Zone: &vpcv1.ZoneIdentityByName{Name: &zoneName},
    Profile: &vpcv1.InstanceProfileIdentityByName{Name: &profileName},
    VPC: &vpcv1.VPCIdentityByID{ID: &vpcID},
    Name: &instanceName,
    PrimaryNetworkAttachment: primaryNetworkAttachment,
}

// Verify fields are set
fmt.Println(instancePrototype.Image != nil)  // true
fmt.Println(instancePrototype.Zone != nil)   // true
fmt.Println(instancePrototype.VPC != nil)    // true

// Marshal to JSON (like the HTTP client does)
jsonBytes, _ := json.Marshal(instancePrototype)
jsonString := string(jsonBytes)

// Check if fields are in JSON
fmt.Println(strings.Contains(jsonString, "image"))    // false (UNEXPECTED)
fmt.Println(strings.Contains(jsonString, "zone"))     // false (UNEXPECTED)
fmt.Println(strings.Contains(jsonString, "vpc"))      // false (UNEXPECTED)

The unit test shows that even though the interface fields are non-nil in Go, they are omitted from the JSON output. This causes the VPC API to receive an incomplete payload that fails oneOf validation.

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