# OneOf Constraint Bug - Root Cause Analysis

## Problem Statement
VPC instance creation fails with error: **"Expected only one oneOf fields to be set: got 0"**

## Error Details
- Test: `TestE2ENodePoolInstanceTypeSelection`
- Circuit breaker triggers after 4-6 failures
- Error message: "creating instance: Expected only one oneOf fields to be set: got 0"

## Root Cause Identified

The code at `pkg/providers/vpc/instance/provider.go:673` calls:
```go
instance, err := vpcClient.CreateInstance(ctx, instancePrototype)
```

However, the **instancePrototype** type is:
```go
*vpcv1.InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment
```

The VPC SDK's `CreateInstance` signature requires:
```go
func (vpc *VpcV1) CreateInstance(createInstanceOptions *CreateInstanceOptions) (result *Instance, response *core.DetailedResponse, err error)
```

## The Issue

The `vpcClient.CreateInstance` wrapper method is likely accepting the raw prototype and wrapping it in `CreateInstanceOptions`, BUT the IBM VPC SDK has a discriminated union (oneOf) pattern for the `InstancePrototype` field within `CreateInstanceOptions`.

When the prototype struct is wrapped or marshaled, the interface fields (`ImageIdentityIntf`, `ZoneIdentityIntf`, etc.) are being lost or set to nil because:

1. **The prototype struct hierarchy is wrong** - The code uses `InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment` which is too specific
2. **Interface field marshaling issue** - The `json:",inline"` or similar tags in the SDK cause interface fields to be omitted when marshaling
3. **Wrapper function might be converting wrong** - If there's a wrapper that converts the prototype to `CreateInstanceOptions`, it might not be preserving the interface types correctly

## Evidence from Logs

Controller logs show (line 654-660):
```go
if jsonBytes, jsonErr := json.MarshalIndent(instancePrototype, "", "  "); jsonErr == nil {
    logger.Info("VPC CreateInstance JSON payload",
        "instance_name", nodeClaim.Name,
        "json_payload", string(jsonBytes))
}
```

The JSON payload from the logs shows that fields WITHOUT `omitempty` are missing:
- `Image ImageIdentityIntf` - NO omitempty, but MISSING in JSON
- `Zone ZoneIdentityIntf` - NO omitempty, but MISSING in JSON
- `PrimaryNetworkAttachment *InstanceNetworkAttachmentPrototype` - NO omitempty, but MISSING in JSON

This indicates the interface values are being set to **nil** during marshaling or prototype wrapping.

## Solution Approach

Need to investigate the `vpcClient.CreateInstance` wrapper method implementation. The fix will likely involve:

1. **Check the wrapper implementation** - See how it converts the prototype to `CreateInstanceOptions`
2. **Use correct prototype type** - May need to use a different prototype type or create `CreateInstanceOptions` directly
3. **Ensure interface fields are preserved** - The wrapper must correctly handle interface type fields

## Next Steps

1. Find the `vpcClient` wrapper interface/implementation
2. Check how `CreateInstance` is wrapping the prototype
3. Verify if the correct oneOf discriminator is being set
4. Test with explicit `CreateInstanceOptions` construction instead of passing raw prototype

## Test Instance Details
- Instance Profile: `bx2-2x8`, `bx2-4x16`, `mx2-2x16`, `cx2-4x8`
- Zone: `eu-de-2`
- Image: `r010-17a6c2b3-c93b-4018-87ca-f078ef21e02b`
- VPC: `r010-2b1c3cdc-a678-4eda-86af-731130de1c0a`
- Subnet: `02c7-dc97437a-1b67-41c9-9db9-a6b92a46963d`

All values are set correctly in code (confirmed by debug logs), but become nil when sent to API.
