{"record":{"id":"262456cde694f9c5","repo":"semaphoreui/semaphore","slug":"cannot-assign-element-of-type-t-to-slice-element","errorCode":null,"errorMessage":"cannot assign element of type %T to slice element of type %s","messagePattern":"cannot assign element of type %T to slice element of type (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/config.go","lineNumber":1218,"sourceCode":"\n\t\t\t\t\t// Build destination slice\n\t\t\t\t\tnewSlice := reflect.MakeSlice(fieldValue.Type(), 0, sourceSlice.Len())\n\t\t\t\t\tfor i := 0; i < sourceSlice.Len(); i++ {\n\t\t\t\t\t\tsrcElemVal := sourceSlice.Index(i)\n\t\t\t\t\t\t// When source is []any, elements come as interface{}, unwrap reflect.Value\n\t\t\t\t\t\tif srcElemVal.Kind() == reflect.Interface && !srcElemVal.IsNil() {\n\t\t\t\t\t\t\tsrcElemVal = reflect.ValueOf(srcElemVal.Interface())\n\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}","sourceCodeStart":1200,"sourceCodeEnd":1236,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/util/config.go#L1200-L1236","documentation":"When filling a slice of structs, each source element must be a map[string]any (to recurse into the struct) or convertible to the element type. If the element is a map of some other type (e.g. map[string]string) this error is returned. It indicates a struct-slice element arrived in a representation the reflector cannot consume.","triggerScenarios":"Assigning []any{map[string]string{...}} or []map[string]string{...} to a field of type []SomeStruct via AssignMapToStruct.","commonSituations":"YAML/TOML decoders producing map[interface{}]interface{} or typed maps inside slices; hand-assembled config slices using non-any map types; JSON re-marshaled into typed maps before assignment.","solutions":["Convert each element map to map[string]any before assignment.","Unmarshal the source document with encoding/json into any so nested objects become map[string]any.","If the element is actually a scalar, either wrap it so it can convert to the struct's element type or fix the field type.","Write a normalization helper that recursively converts maps to map[string]any and apply it to the whole input map."],"exampleFix":"// before\nitems := []map[string]string{{\"name\": \"a\"}}\nm := map[string]any{\"items\": items} // field is []Item\n// after\nm := map[string]any{\"items\": []any{map[string]any{\"name\": \"a\"}}}","handlingStrategy":"type-guard","validationCode":"for _, e := range items.([]any) {\n  if _, ok := e.(map[string]any); !ok {\n    return fmt.Errorf(\"slice elements must be objects (map[string]any)\")\n  }\n}","typeGuard":"func isStringAnyMapSlice(v any) bool {\n  s, ok := v.([]any)\n  if !ok { return false }\n  for _, e := range s {\n    if _, ok := e.(map[string]any); !ok { return false }\n  }\n  return true\n}","tryCatchPattern":"if err := util.AssignMapToStruct(m, &cfg); err != nil {\n  if strings.Contains(err.Error(), \"cannot assign element of type\") {\n    log.Fatalf(\"struct-slice element shape wrong: %v\", err)\n  }\n}","preventionTips":["Use encoding/json for all config decoding so nested objects become map[string]any.","Avoid YAML/TOML decoders that emit map[interface{}]interface{} without conversion.","Write one recursive normalization helper and apply it to all external config input."],"tags":["reflection","config","go","slice","type-assertion"],"backgroundTag":"incompatible-source-type","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"}