{"record":{"id":"54cf4f92684542a5","repo":"wavetermdev/waveterm","slug":"error-setting-field-s-w","errorCode":null,"errorMessage":"error setting field %s: %w","messagePattern":"error setting field (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/util/utilfn/marshal.go","lineNumber":85,"sourceCode":"\t\treturn fmt.Errorf(\"out parameter must be a pointer to struct, got pointer to %v\", elem.Kind())\n\t}\n\n\t// Get type information\n\ttyp := elem.Type()\n\n\t// For each field in the struct\n\tfor i := 0; i < typ.NumField(); i++ {\n\t\tfield := typ.Field(i)\n\n\t\t// Skip unexported fields\n\t\tif !field.IsExported() {\n\t\t\tcontinue\n\t\t}\n\n\t\tname := getJSONName(field)\n\t\tif value, ok := in[name]; ok {\n\t\t\tif err := setValue(elem.Field(i), value); err != nil {\n\t\t\t\treturn fmt.Errorf(\"error setting field %s: %w\", name, err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc StructToMap(in any) (map[string]any, error) {\n\t// Get value and handle pointer\n\tval := reflect.ValueOf(in)\n\tif val.Kind() == reflect.Ptr {\n\t\tval = val.Elem()\n\t}\n\n\t// Check that we have a struct\n\tif val.Kind() != reflect.Struct {\n\t\treturn nil, fmt.Errorf(\"input must be a struct or pointer to struct, got %v\", val.Kind())\n\t}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/util/utilfn/marshal.go#L67-L103","documentation":"MapToStruct matched a struct field by its JSON name and found a value in the input map, but setValue failed while coercing/storing it; this wrapper adds the field name for context via %w. The root cause is inside setValue — type mismatch, non-convertible types, or kind-specific set failures.","triggerScenarios":"Input map has \"port\": \"8080\" (string) for an int field with no convertible path handled, \"tags\": \"a,b\" for []string, a nested object for a non-struct field, or null/nil handling gaps — setValue's error is wrapped with the offending field name.","commonSituations":"JSON/YAML config files with values typed as strings by the parser being fed into typed structs; API payloads with numbers-as-strings; schema drift between producer and struct definition.","solutions":["Read the wrapped inner error to see the exact type conflict, then fix the source data or the struct field type","Pre-normalize the map: convert string numbers to numbers (strconv) before calling MapToStruct","Use flexible field types (json.Number, custom scalar types with UnmarshalJSON) for loose inputs","Add per-field validation of the input map before conversion to catch bad values early"],"exampleFix":"// before\nraw := map[string]any{\"port\": \"8080\"}\nvar cfg Config // Port int\nerr := utilfn.MapToStruct(raw, &cfg) // error setting field port: ...\n// after\nif s, ok := raw[\"port\"].(string); ok {\n    if n, cerr := strconv.Atoi(s); cerr == nil {\n        raw[\"port\"] = n\n    }\n}\nerr := utilfn.MapToStruct(raw, &cfg)","handlingStrategy":"validation","validationCode":"// normalize common string->typed values before MapToStruct\nfor k, v := range in {\n    if s, ok := v.(string); ok {\n        if n, err := strconv.Atoi(s); err == nil { in[k] = n; continue }\n        if b, err := strconv.ParseBool(s); err == nil { in[k] = b }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := utilfn.MapToStruct(in, &cfg); err != nil {\n    var fname string\n    if strings.Contains(err.Error(), \"error setting field \") {\n        fmt.Sscanf(err.Error(), \"error setting field %s\", &fname)\n        log.Printf(\"bad value for field %q: %v\", fname, err)\n    }\n}","preventionTips":["Pre-normalize loose config maps (string numbers/bools) before conversion","Keep struct field types aligned with the producing format's types","Validate the map against the struct schema before conversion"],"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"}