diff --git a/changelog/pending/20221028--sdk-go-yaml--prevent-race-on-resource-output.yaml b/changelog/pending/20221028--sdk-go-yaml--prevent-race-on-resource-output.yaml new file mode 100644 index 000000000000..855e425d88ee --- /dev/null +++ b/changelog/pending/20221028--sdk-go-yaml--prevent-race-on-resource-output.yaml @@ -0,0 +1,4 @@ +changes: +- type: fix + scope: sdk/go,yaml + description: Prevent race on resource output diff --git a/sdk/go/pulumi/context.go b/sdk/go/pulumi/context.go index d3c0515724c8..0ec0534d9ab8 100644 --- a/sdk/go/pulumi/context.go +++ b/sdk/go/pulumi/context.go @@ -1178,8 +1178,6 @@ func (state *resourceState) resolve(ctx *Context, err error, inputs *resourceInp return } - state.rawOutputs.getState().resolve(outprops, true, false, nil) - outprops["urn"] = resource.NewStringProperty(urn) if id != "" || !dryrun { outprops["id"] = resource.NewStringProperty(id) @@ -1204,6 +1202,10 @@ func (state *resourceState) resolve(ctx *Context, err error, inputs *resourceInp } } + // We need to wait until after we finish mutating outprops to resolve. Resolving + // unlocks multithreaded access to the resolved value, making mutation a data race. + state.rawOutputs.getState().resolve(outprops, true, false, nil) + for k, output := range state.outputs { // If this is an unknown or missing value during a dry run, do nothing. v, ok := outprops[resource.PropertyKey(k)]