{"record":{"id":"8c59fe88072ee9c0","repo":"pulumi/pulumi","slug":"expected-a-s-got-an-asset-8c59fe","errorCode":null,"errorMessage":"expected a %s, got an asset","messagePattern":"expected a (.+?), got an asset","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdk/go/pulumi/rpc.go","lineNumber":822,"sourceCode":"\t// pointer allocation to preserve the nil zero value for pointer destinations.\n\tif v.IsOutput() && v.OutputValue().Element.IsNull() {\n\t\treturn v.OutputValue().Secret, nil\n\t}\n\n\tallocatedPointer := false\n\t// Allocate storage as necessary.\n\tfor dest.Kind() == reflect.Pointer {\n\t\tallocatedPointer = true\n\t\telem := reflect.New(dest.Type().Elem())\n\t\tdest.Set(elem)\n\t\tdest = elem.Elem()\n\t}\n\n\t// In the case of assets and archives, turn these into real asset and archive structures.\n\tswitch {\n\tcase v.IsAsset():\n\t\tif !assetType.AssignableTo(dest.Type()) {\n\t\t\treturn false, fmt.Errorf(\"expected a %s, got an asset\", dest.Type())\n\t\t}\n\n\t\tasset, secret, err := unmarshalPropertyValue(ctx, v)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\tdest.Set(reflect.ValueOf(asset))\n\t\treturn secret, nil\n\tcase v.IsArchive():\n\t\tif !archiveType.AssignableTo(dest.Type()) {\n\t\t\treturn false, fmt.Errorf(\"expected a %s, got an archive\", dest.Type())\n\t\t}\n\n\t\tarchive, secret, err := unmarshalPropertyValue(ctx, v)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\tdest.Set(reflect.ValueOf(archive))","sourceCodeStart":804,"sourceCodeEnd":840,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/sdk/go/pulumi/rpc.go#L804-L840","documentation":"unmarshalOutput writes a wire property value into a reflect destination (e.g. a typed result struct for a resource method's outputs). When the value is an Asset, the destination type must be assignable from the SDK's Asset interface (assetType); otherwise the SDK refuses with 'expected a %s, got an asset' (rpc.go:822), naming the destination type it actually received.","triggerScenarios":"Declaring an output/result field of a non-asset type (string, pulumi.StringOutput, interface{}, custom struct) while the engine returns an Asset for that property - e.g. in a resource method's Check/Invoke-style outputs struct or a GetX result field typed wrongly.","commonSituations":"Mismatch between the Pulumi schema (which says a property is an asset) and a hand-written Go result struct; copying a result struct from another language SDK where the property was a plain string; schema drift after a provider upgrade changed the property to an AssetOrArchive.","solutions":["Change the destination field's type to pulumi.Asset (or the concrete asset type) so it is assignable from assetType.","Regenerate or update the provider's Go SDK so result structs match the schema's asset-typed properties.","If the value should be a string, extract it at the call site from the concrete asset (e.g. type-switch to *FileAsset/*StringAsset/*RemoteAsset) rather than typing the field as string.","Check the provider schema (`pulumi schema`) to confirm the property's expected type and align the struct."],"exampleFix":"// before\ntype GetResult struct {\n    Content string\n}\n// after\ntype GetResult struct {\n    Content pulumi.Asset\n}","handlingStrategy":"type-guard","validationCode":"func expectsAsset(dest reflect.Value, v resource.PropertyValue) bool {\n    return !v.IsAsset() || reflect.TypeOf((*pulumi.Asset)(nil)).Elem().AssignableTo(dest.Type())\n}","typeGuard":"func destAcceptsAsset(destType reflect.Type) bool {\n    return reflect.TypeOf((*pulumi.Asset)(nil)).Elem().AssignableTo(destType)\n}","tryCatchPattern":"if err := result.Unmarshal(ctx, resp.Return); err != nil {\n    if strings.Contains(err.Error(), \"got an asset\") {\n        return fmt.Errorf(\"result struct field must be pulumi.Asset for asset-typed schema property: %w\", err)\n    }\n    return err\n}","preventionTips":["Type result/output struct fields as pulumi.Asset when the schema marks the property as an asset","Regenerate provider SDKs after schema changes instead of hand-editing structs","Check `pulumi schema` output to confirm property types before writing result structs"],"tags":["go","asset","type-mismatch"],"backgroundTag":"asset-type-mismatch","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}