pulumi/pulumi · error

unmarshaling replacement trigger: %w

Error message

unmarshaling replacement trigger: %w

What it means

When constructing a component, the SDK may unmarshal a 'replacement trigger' value from the request's aliases/options using plugin.UnmarshalProperties (sdk/go/pulumi/provider.go:160). Failure to decode that property map aborts Construct with 'unmarshaling replacement trigger'.

Source

Thrown at sdk/go/pulumi/provider.go:160

		hooks.BeforeDelete = makeStubHooks(binding.GetBeforeDelete())
		hooks.AfterDelete = makeStubHooks(binding.GetAfterDelete())
		hooks.OnError = makeStubErrorHooks(binding.GetOnError())
	}

	var replacementTrigger Input
	if rt := req.GetReplacementTrigger(); rt != nil {
		pv, err := plugin.UnmarshalPropertyValue(
			resource.PropertyKey("replacementTrigger"),
			rt,
			plugin.MarshalOptions{
				KeepSecrets:      true,
				KeepResources:    true,
				KeepUnknowns:     req.GetDryRun(),
				KeepOutputValues: true,
			},
		)
		if err != nil {
			return nil, fmt.Errorf("unmarshaling replacement trigger: %w", err)
		}

		if pv != nil && !pv.IsNull() { // null = explicitly unset
			m, err := unmarshalPropertyMap(pulumiCtx, resource.PropertyMap{
				resource.PropertyKey("replacementTrigger"): *pv,
			})
			if err != nil {
				return nil, fmt.Errorf("unmarshaling replacement trigger: %w", err)
			}
			replacementTrigger = m["replacementTrigger"]
		}
	}

	opts := resourceOption(func(ro *resourceOptions) {
		ro.Aliases = aliases
		if len(dependencies) > 0 {
			ro.DependsOn = append(ro.DependsOn, resourceDependencySet(dependencies))
		}

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Check the wrapped error for the specific property that failed to decode
  2. Align engine and sdk/go versions (replacement-trigger encoding changed across releases)
  3. Verify the caller passing replacement triggers marshals them with plugin.MarshalProperties
  4. Simplify the replacement trigger to plain values (strings/numbers) if custom encodings are unnecessary
Defensive patterns

Strategy: validation

Validate before calling

// ensure the replacement trigger value only contains marshal-safe primitives
func safeTrigger(v interface{}) error {
	switch v.(type) {
	case nil, string, int, float64, bool:
		return nil
	default:
		return fmt.Errorf("unsupported trigger type %T", v)
	}
}

Try / catch

pv, err := plugin.UnmarshalProperties(raw, opts)
if err != nil {
	return nil, fmt.Errorf("unmarshaling replacement trigger: %w", err)
}

Prevention

When it happens

Trigger: plugin.UnmarshalProperties on the replacement-trigger protobuf value returns an error (options KeepResources/KeepUnknowns/KeepOutputValues apply).

Common situations: A replacement trigger containing secret or output-value encodings the SDK cannot decode, or a malformed property map produced by a mismatched engine/SDK version.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/d23de880d5376fd7. Report an issue: GitHub.