Skip to content

Dynamic-bridge path drops empty nested collections: absent blocks read as null and diverge from OpenTofu #508

Description

@iwahbe

Running the tfcompat suite through the real terraform-provider plugin (parameterized reattach path, #505) surfaced a family of deterministic output divergences that the in-process bridged path masked. The common shape: where OpenTofu materializes an absent or emptied nested collection as an empty list/set, the dynamic-bridge path materializes it as null (the pf property projection drops nested empty collections, and pulumi-hcl projects the missing property as null).

Three skipped tfcompat cases reproduce it (each has a putest twin locking in the current behavior):

  • tests/tfcompat/l2_omitted_nested_block — an optional MaxItems=1 nested block (rule) left out of an enclosing block: OpenTofu reads policy[0].rule as [] (length 0); pulumi-hcl reads null, so length(policy[0].rule) fails the deploy with Invalid value for "value" parameter: argument must not be null.
  • tests/tfcompat/l2_optional_computed_block_unset — an Optional+Computed MaxItems=1 TypeSet block the provider leaves unset: OpenTofu keeps an empty set (== null false, jsonencode"[]"); pulumi-hcl reads null. (The TypeList variant agrees on null in both.)
  • tests/tfcompat/l2_ignore_changes_forcenew_block_removed — removing a MaxItems=1 block whose ForceNew attribute is in ignore_changes: both runtimes replace the resource and create the replacement with settings = [], but pulumi-hcl's settings output still reports the removed block's old value where OpenTofu reports [].

To reproduce, re-enable any of the three skipped tests and run it with terraform-provider ≥ 1.3.0 installed:

go test ./tests/tfcompat/ -run TestL2OmittedNestedBlock -v -count=1

The correct (OpenTofu-matching) behavior is pinned against the linked-in bridged provider by tests/putest/l2_block_projection_test.go — the divergence is specific to the plugin path. When this is fixed, re-enable the tfcompat cases and drop the putest twins.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugSome behavior is incorrect or out of spec

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions