{"record":{"id":"415ba1b02c6b35bb","repo":"semaphoreui/semaphore","slug":"cannot-assign-element-of-type-s-to-slice-element","errorCode":null,"errorMessage":"cannot assign element of type %s to slice element of type %s","messagePattern":"cannot assign element of type (.+?) to slice element of type (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/config.go","lineNumber":1226,"sourceCode":"\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar dstElem reflect.Value\n\t\t\t\t\t\t// Prepare destination element\n\t\t\t\t\t\tif fieldElemType.Kind() == reflect.Struct {\n\t\t\t\t\t\t\tdstElem = reflect.New(fieldElemType).Elem()\n\t\t\t\t\t\t\tif srcElemVal.Kind() == reflect.Map {\n\t\t\t\t\t\t\t\t// Expect map[string]any\n\t\t\t\t\t\t\t\tmIface, ok := srcElemVal.Interface().(map[string]any)\n\t\t\t\t\t\t\t\tif !ok {\n\t\t\t\t\t\t\t\t\treturn fmt.Errorf(\"cannot assign element of type %T to slice element of type %s\", srcElemVal.Interface(), fieldElemType)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif err := assignMapToStructRecursive(mIface, dstElem); err != nil {\n\t\t\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if srcElemVal.Type().ConvertibleTo(fieldElemType) {\n\t\t\t\t\t\t\t\tdstElem = srcElemVal.Convert(fieldElemType)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn fmt.Errorf(\"cannot assign element of type %s to slice element of type %s\", srcElemVal.Type(), fieldElemType)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Primitive or other kinds\n\t\t\t\t\t\t\tif srcElemVal.Type().ConvertibleTo(fieldElemType) {\n\t\t\t\t\t\t\t\tdstElem = srcElemVal.Convert(fieldElemType)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tnewVal, converted := CastValueToKind(srcElemVal.Interface(), fieldElemType.Kind())\n\t\t\t\t\t\t\t\tif !converted {\n\t\t\t\t\t\t\t\t\treturn fmt.Errorf(\"cannot assign element of type %s to slice element of type %s\", srcElemVal.Type(), fieldElemType)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tdstElem = reflect.ValueOf(newVal)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnewSlice = reflect.Append(newSlice, dstElem)\n\t\t\t\t\t}\n\n\t\t\t\t\tfieldValue.Set(newSlice)","sourceCodeStart":1208,"sourceCodeEnd":1244,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/util/config.go#L1208-L1244","documentation":"For slice-of-struct fields, if the source element is not a map, the reflector tries reflect Convertibility to the struct element type; a scalar that is not directly convertible to the struct type (which scalars never are) hits this error. It means a non-map, non-convertible value was given where a struct element (or its map form) was expected.","triggerScenarios":"Assigning []any{\"web-1\", 42} to a []SomeStruct field via AssignMapToStruct — string/int elements cannot convert to a struct type.","commonSituations":"Config lists of names/IDs mapped onto a []struct field that expects objects (e.g. [{\"name\": ...}]); a schema change turned struct elements into plain identifiers; copy-paste error in the map keys.","solutions":["Supply each element as map[string]any matching the struct's JSON keys, e.g. [{\"name\": \"web-1\"}].","Change the struct field to a slice of the scalar type if the data is genuinely scalar.","Pre-convert scalar elements into struct values yourself before calling AssignMapToStruct.","Check the field's json/db tags to confirm the config key maps to the intended slice field."],"exampleFix":"// before\nm := map[string]any{\"servers\": []any{\"web-1\"}} // field is []Server\n// after\nm := map[string]any{\"servers\": []any{map[string]any{\"name\": \"web-1\"}}}","handlingStrategy":"validation","validationCode":"for _, e := range elems.([]any) {\n  if _, ok := e.(map[string]any); !ok {\n    return fmt.Errorf(\"struct slice needs object elements, got %T\", e)\n  }\n}","typeGuard":"func isObjectElement(e any) bool {\n  _, ok := e.(map[string]any)\n  return ok\n}","tryCatchPattern":"defer func() {\n  if err := util.AssignMapToStruct(m, &cfg); err != nil {\n    log.Fatalf(\"config assignment failed: %v\", err)\n  }\n}()","preventionTips":["Check whether the field is []Struct vs []string before building the config map.","Keep schema docs aligned with struct definitions when changing field types.","Wrap scalars into objects ({\"name\": ...}) when the target is a slice of structs."],"tags":["reflection","config","go","slice","type-conversion"],"backgroundTag":"config-type-mismatch","analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}