pulumi/pulumi · error

unmarshaling __self__: %w

Error message

unmarshaling __self__: %w

What it means

callArgsSelf wraps any failure from unmarshalPropertyValue while decoding the `__self__` resource argument as "unmarshaling __self__: %w". It means the raw gRPC value sent for the resource receiver could not be converted back into a Go Resource (malformed property map, missing required fields like __self__'s URN/type, or an unsupported value inside it).

Source

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

	return self, nil
}

// callArgsSelf retrieves the `__self__` argument. If `__self__` is present the value is returned,
// otherwise the returned value will be nil.
func callArgsSelf(ctx *Context, source map[string]any) (Resource, error) {
	v, ok := source["__self__"]
	if !ok {
		return nil, nil
	}

	ci := v.(*constructInput)
	if ci.value.ContainsUnknowns() {
		return nil, errors.New("__self__ is unknown")
	}

	value, secret, err := unmarshalPropertyValue(ctx, ci.value)
	if err != nil {
		return nil, fmt.Errorf("unmarshaling __self__: %w", err)
	}
	if secret {
		return nil, errors.New("__self__ is a secret")
	}

	return value.(Resource), nil
}

// newCallResult converts a result struct into an input Map that can be marshalled.
func newCallResult(result any) (Input, error) {
	if result == nil {
		return nil, errors.New("result must not be nil")
	}

	resultV := reflect.ValueOf(result)
	typ := resultV.Type()
	if typ.Kind() != reflect.Pointer || typ.Elem().Kind() != reflect.Struct {
		return nil, errors.New("result must be a pointer to a struct")

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Read the wrapped cause after 'unmarshaling __self__:' — it names the specific value that failed to decode
  2. Verify engine and Go SDK versions are compatible (upgrade the SDK to match your CLI)
  3. Check the receiver resource's inputs/state for unsupported nested types (functions, channels, unregistered structs)
  4. Reproduce with a minimal program to determine whether the issue is in the resource definition or the Call transport
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify receiver state only contains round-trippable values before registering the resource
if hasUnsupportedNestedTypes(resourceArgs) {
    return errors.New("receiver state contains types that cannot round-trip through gRPC")
}

Type guard

func isResourceValue(v any) bool {
    _, ok := v.(Resource)
    return ok
}

Try / catch

value, secret, err := unmarshalPropertyValue(ctx, ci.value)
if err != nil {
    return nil, fmt.Errorf("unmarshaling __self__: %w", err)
}
// caller: inspect errors.Unwrap(err) to identify the failing field

Prevention

When it happens

Trigger: A method-style Call whose `__self__` serialized value cannot round-trip through unmarshalPropertyValue: the engine sent a property map missing registration metadata, a nested value type the unmarshaler rejects, or the resource state contains an unsupported nested type.

Common situations: Version mismatch between engine and Go SDK (marshal/unmarshal behavior drift); custom resources whose state includes types not representable in the gRPC value model; corrupted or hand-crafted Call requests.

Related errors


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