{"record":{"id":"d841423d829b8472","repo":"wavetermdev/waveterm","slug":"cannot-set-value-of-type-v-to-field-of-type-v","errorCode":null,"errorMessage":"cannot set value of type %v to field of type %v","messagePattern":"cannot set value of type (.+?) to field of type (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/util/utilfn/marshal.go","lineNumber":165,"sourceCode":"\n\t// Check if types are assignable\n\tif valueRef.Type().AssignableTo(field.Type()) {\n\t\tfield.Set(valueRef)\n\t\treturn nil\n\t}\n\n\t// If field is pointer and value isn't already a pointer, try address\n\tif field.Kind() == reflect.Ptr && valueRef.Kind() != reflect.Ptr {\n\t\treturn setValue(field, valueRef.Addr().Interface())\n\t}\n\n\t// Try conversion if types are convertible\n\tif valueRef.Type().ConvertibleTo(field.Type()) {\n\t\tfield.Set(valueRef.Convert(field.Type()))\n\t\treturn nil\n\t}\n\n\treturn fmt.Errorf(\"cannot set value of type %v to field of type %v\", valueRef.Type(), field.Type())\n}\n\n// DecodeDataURL decodes a data URL and returns the mimetype and raw data bytes\nfunc DecodeDataURL(dataURL string) (mimeType string, data []byte, err error) {\n\tif !strings.HasPrefix(dataURL, \"data:\") {\n\t\treturn \"\", nil, fmt.Errorf(\"invalid data URL: must start with 'data:'\")\n\t}\n\n\tparts := strings.SplitN(dataURL, \",\", 2)\n\tif len(parts) != 2 {\n\t\treturn \"\", nil, fmt.Errorf(\"invalid data URL format: missing comma separator\")\n\t}\n\n\theader := parts[0]\n\tdataStr := parts[1]\n\n\t// Parse mimetype from header: \"data:text/plain;base64\" -> \"text/plain\"\n\theaderWithoutPrefix := strings.TrimPrefix(header, \"data:\")","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/util/utilfn/marshal.go#L147-L183","documentation":"setValue is MapToStruct's field-assignment helper. After trying direct assignment and ConvertibleTo-based conversion, it gives up if the input value's type still cannot be stored in the field type, reporting both types. Non-convertible cases include string→slice, map→struct, and different named types without convertible underlying kinds.","triggerScenarios":"Setting []string field from a string value; bool field from \"true\" string (strconv not attempted); time.Time field from an int64 timestamp; named type mismatch where ConvertibleTo is false (e.g. func/map kinds).","commonSituations":"Loosely typed config formats (YAML/TOML parsers yielding map[string]any of strings) feeding strictly typed structs; version drift where a struct field changed type; hand-built maps with JSON-ish values of wrong types.","solutions":["Convert the value in the caller to the exact field type before calling MapToStruct (strconv, json.Unmarshal into the target, etc.)","Implement UnmarshalJSON on custom field types if the data shape is fixed but the representation is loose","Use encoding/json's map→struct path (json.Marshal then json.Unmarshal) which handles more coercions, if performance allows","Align the struct field type with the real data type (e.g. use json.Number or string fields for stringly-typed sources)"],"exampleFix":"// before\nraw := map[string]any{\"tags\": \"a,b\"} // Tags []string\nvar cfg Config\nutilfn.MapToStruct(raw, &cfg) // cannot set value of type string to field of type []string\n// after\nraw[\"tags\"] = strings.Split(\"a,b\", \",\")\nutilfn.MapToStruct(raw, &cfg) // ok","handlingStrategy":"validation","validationCode":"func canSet(field reflect.Value, val any) bool {\n    v := reflect.ValueOf(val)\n    return v.Type().AssignableTo(field.Type()) || v.Type().ConvertibleTo(field.Type())\n}","typeGuard":null,"tryCatchPattern":"if err := utilfn.MapToStruct(in, &cfg); err != nil {\n    if strings.Contains(err.Error(), \"cannot set value of type\") {\n        // coerce the offending value manually and retry\n    }\n}","preventionTips":["Match value types to field types before conversion (strconv/json round-trip)","Use json.Number or custom types with UnmarshalJSON for loose data","Prefer encoding/json for map→struct when heavy coercion is needed"],"tags":["reflection","go","type-mismatch","marshaling"],"backgroundTag":"type-conversion-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}