Skip to content

Discriminated unions with 3+ members collapse to object in generated SDKs #1098

Description

@lukebward

Summary

When a schema property is a oneOf union of 3+ object types, the generated .NET SDK types the property as object, even when the union carries a discriminator with a complete mapping. InputUnion<T0, T1> only covers the 2-member case, and the discriminator is ignored by SDK codegen. Everything needed to generate a typed representation is in the schema but unused. The same SDK build shows the 2-member case working fine: a string | object union renders as InputUnion<string, Inputs.DockerImageRequestArgs>.

Example

pulumi-pulumiservice emits this for a recursive RBAC expression tree:

"left": {
  "oneOf": [
    { "$ref": "#/types/pulumiservice:api:PermissionExpressionAnd" },
    { "$ref": "#/types/pulumiservice:api:PermissionExpressionOr" },
    { "$ref": "#/types/pulumiservice:api:PermissionExpressionNot" },
    ... 17 variants total ...
  ],
  "discriminator": {
    "propertyName": "__type",
    "mapping": { "PermissionExpressionAnd": "#/types/pulumiservice:api:PermissionExpressionAnd", ... }
  }
}

Generated C# today:

public sealed class PermissionExpressionOrArgs : global::Pulumi.ResourceArgs
{
    [Input("__type", required: true)]
    public Input<string> __type { get; set; } = null!;

    [Input("left")]
    public object? Left { get; set; }   // <- should be constrained to the 17 variants

    [Input("right")]
    public object? Right { get; set; }
}

TypeScript renders the full tagged union from the same schema, so a wrong or misspelled variant is a compile error. C# accepts any object and the mistake surfaces at deploy time, or not at all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageNeeds attention from the triage team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions