Skip to content

plugin/external/convert.go:mapToStruct silently drops Outputs on structpb.NewStruct errors #537

Description

@intel352

Bug

plugin/external/convert.go:20-30 mapToStruct falls back to an empty *structpb.Struct{} when structpb.NewStruct(m) returns an error:

```go
func mapToStruct(m map[string]any) *structpb.Struct {
if m == nil {
return nil
}
s, err := structpb.NewStruct(m)
if err != nil {
return &structpb.Struct{} // silent drop — should propagate
}
return s
}
```

Result: providers whose ResourceOutput.Outputs or DiffResult.Changes carry types structpb cannot represent (chan, func, *time.Time without MarshalJSON, custom struct without map representation) silently drop those fields on the wire. Downstream consumers (state persistence, drift detection, cross-module substitution) see an empty Outputs map and treat it as "no changes" — masking real provider bugs.

Surfaced by

W-7 conformance suite — Scenario_DiffSurvivesGRPCRoundTrip (in iac/conformance/scenario_grpc_roundtrip.go) is intentionally stricter than this production wire so the underlying provider bug surfaces before the wire layer hides it. Reviewed in PR #535 by Copilot:
#535 (comment)

Fix sketch

Propagate the error rather than swallowing it:

```go
func mapToStruct(m map[string]any) (*structpb.Struct, error) {
if m == nil {
return nil, nil
}
s, err := structpb.NewStruct(m)
if err != nil {
return nil, fmt.Errorf("structpb.NewStruct: %w", err)
}
return s, nil
}
```

This is a signature-changing fix; the same shape exists in plugin/external/sdk/grpc_server.go:575. Both call sites need a coordinated bump. Estimate: small (5-10 file diff), but every caller needs to handle the error path. Not appropriate for W-7 scope; tracked here as the architecturally-correct counterpart to the conformance-suite strictness.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions