semaphoreui/semaphore · error
cannot assign value of type
Error message
cannot assign value of type %s to map element of type %s
What it means
When populating a map field with non-struct element type, each value must be reflect-convertible to the map's element type or castable by CastValueToKind (which supports string, int, bool kinds). If neither works — e.g. a string value into a map[string]float64, or any value into a map with an unsupported element kind — this error is returned.
Solutions
- Provide values already typed as the map's element type (e.g. 1.5 not "1.5" for map[string]float64).
- If values are strings, ensure they parse cleanly for the target kind and consider pre-casting yourself.
- Change the map field's element type to string, int, or bool (supported by CastValueToKind).
- Convert the whole source map to the typed map before calling AssignMapToStruct.
Example fix
// before
m := map[string]any{"limits": map[string]any{"cpu": "1.5"}} // field is map[string]float64
// after
m := map[string]any{"limits": map[string]any{"cpu": 1.5}} Defensive patterns
Strategy: validation
Validate before calling
for k, v := range srcMap {
switch v.(type) {
case string, int, bool, float64:
default:
return fmt.Errorf("map value %q has unsupported type %T", k, v)
}
} Type guard
func castableToKind(v any, k reflect.Kind) bool {
switch k {
case reflect.String, reflect.Int, reflect.Bool:
return true
}
return reflect.TypeOf(v).ConvertibleTo(reflect.SliceOf(reflect.InterfaceOf(nil)).Type()) // else pre-check manually
} Try / catch
if err := util.AssignMapToStruct(m, &cfg); err != nil {
if strings.Contains(err.Error(), "cannot assign value of type") {
log.Fatalf("map element type unsupported: %v", err)
}
} Prevention
- Match value types to the map's declared element type in source maps.
- Restrict map element types to string, int, bool where possible.
- Cast numeric strings to numbers at the config ingestion point.
When it happens
Trigger: Assigning map[string]any{"k": "1.5"} to a map[string]float64 field, or values with unparseable text ("abc") into map[string]int/map[string]bool fields.
Common situations: Numeric/float settings sourced from env vars as strings; typos in numeric config values; map fields with less-common element types (float, uint, custom kinds) that CastValueToKind does not handle.
Related errors
- expected map for field
- cannot assign value of type %T to field
- expected slice or json array string for field
- expected slice for field
- cannot assign element of type %T to slice element of type
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/860d1faa788a4401.
Report an issue: GitHub.
Appendix: source
Thrown at util/config.go:1278
srcVal := fieldValue.MapIndex(key)
var mapElem reflect.Value
if srcVal.IsValid() {
mapElem = cloneStruct(srcVal)
} else {
mapElem = reflect.New(mapElemType).Elem()
}
if mapElemType.Kind() == reflect.Struct {
if err := assignMapToStructRecursive(mapElemValue.Interface().(map[string]any), mapElem); err != nil {
return err
}
} else {
if mapElemValue.Type().ConvertibleTo(mapElemType) {
mapElem.Set(mapElemValue.Convert(mapElemType))
} else {
newVal, converted := CastValueToKind(mapElemValue.Interface(), mapElemType.Kind())
if !converted {
return fmt.Errorf("cannot assign value of type %s to map element of type %s",
mapElemValue.Type(), mapElemType)
}
mapElem.Set(reflect.ValueOf(newVal))
}
}
fieldValue.SetMapIndex(key, mapElem)
}
default:
// Handle simple types
if val.Type().ConvertibleTo(fieldValue.Type()) {
fieldValue.Set(val.Convert(fieldValue.Type()))
} else {
newVal, converted := CastValueToKind(val.Interface(), fieldValue.Type().Kind())
if !converted {View on GitHub (pinned to 1774ccb71a)