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

  1. Provide values already typed as the map's element type (e.g. 1.5 not "1.5" for map[string]float64).
  2. If values are strings, ensure they parse cleanly for the target kind and consider pre-casting yourself.
  3. Change the map field's element type to string, int, or bool (supported by CastValueToKind).
  4. 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

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


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)