pulumi/pulumi · error

expected a %s, got a resource of type %s

Error message

expected a %s, got a resource of type %s

What it means

Thrown by the Go SDK's property unmarshaling when a deserialized value is a resource reference whose concrete resource type is not assignable to the destination type (sdk/go/pulumi/rpc.go:863). During `unmarshalOutput`, the engine sends back a resource reference (URN + optional ID); the SDK instantiates the typed resource wrapper and checks `resV.Elem().Type().AssignableTo(dest.Type())`. When the provider returns a resource of a different type than the struct field being populated, the assignability check fails and this error is returned.

Source

Thrown at sdk/go/pulumi/rpc.go:863

		}
		return true, nil
	case v.IsResourceReference():
		res, secret, err := unmarshalPropertyValue(ctx, v)
		if err != nil {
			return false, err
		}
		resV := reflect.ValueOf(res)
		// If we unmarshal a pointer and the destination is "any", we also want to make sure the result is a
		// pointer.  We check above whether the destination is a pointer, but that's not true for "any", even
		// though it can hold a pointer.
		if !allocatedPointer && resV.Kind() == reflect.Pointer && dest.Type().Kind() == reflect.Interface &&
			resV.Elem().Type().AssignableTo(dest.Type()) {
			dest.Set(resV)
			return secret, nil
		}

		if !resV.Elem().Type().AssignableTo(dest.Type()) {
			return false, fmt.Errorf("expected a %s, got a resource of type %s", dest.Type(), resV.Type())
		}
		dest.Set(resV.Elem())
		return secret, nil
	case v.IsOutput():
		if _, err := unmarshalOutput(ctx, v.OutputValue().Element, dest); err != nil {
			return false, err
		}
		return v.OutputValue().Secret, nil
	}

	// Unmarshal based on the desired type.
	//nolint:exhaustive // We only need to handle a few types here.
	switch dest.Kind() {
	case reflect.Bool:
		if !v.IsBool() {
			return false, fmt.Errorf("expected a %v, got a %s", dest.Type(), v.TypeString())
		}
		dest.SetBool(v.BoolValue())

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Check the actual resource type returned by the provider (log the URN) and align the destination struct field type with it.
  2. Ensure the Go SDK version of the provider matches the provider version actually deployed (run `pulumi plugin ls` and `pulumi up` to refresh state).
  3. If the value may genuinely be either resource type, unmarshal into `pulumi.ResourceOutput` or `pulumi.AnyOutput` and assert type in an Apply.
  4. Regenerate the provider SDK so generated resource types match the provider schema.

Example fix

// before
var buckets pulumi.StringOutput = bucket.ID()
// error: expected a pulumi.StringOutput, got a resource of type aws.s3.Bucket

// after
var bucket pulumi.AwsS3BucketOutput
bucket.ApplyT(func(b *awss3.Bucket) (string, error) { return b.ID().ToStringOutput() })
Defensive patterns

Strategy: type-guard

Validate before calling

if b, ok := someOutput.(pulumi.AwsS3BucketOutput); !ok {
    return fmt.Errorf("output is not an AwsS3Bucket")
}

Type guard

func isBucket(v interface{}) bool {
    _, ok := v.(*awss3.Bucket)
    return ok
}

Try / catch

err := ...unmarshal...
if err != nil && strings.Contains(err.Error(), "got a resource of type") {
    // log URN / resource type and fall back to a generic resource output
}

Prevention

When it happens

Trigger: Calling `resource.Output<T>(...)` / `GetResource` style APIs where the engine returns a resource reference of type A but the destination field is typed as resource B. Also happens when a provider is upgraded/renamed and returns resources with a different URN type token, or when hand-crafted property values passed through custom resource outputs don't match the declared Go type.

Common situations: Provider version mismatch: a resource renamed between provider versions returns a URN whose type token no longer matches the Go SDK's generated type. Using the same output struct for resources from different providers. Copy-pasted apply functions casting outputs to the wrong resource type.

Related errors


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