semaphoreui/semaphore · error

cannot assign element of type %T to slice element of type

Error message

cannot assign element of type %T to slice element of type %s

What it means

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.

Solutions

  1. Convert each element map to map[string]any before assignment.
  2. Unmarshal the source document with encoding/json into any so nested objects become map[string]any.
  3. 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.
  4. Write a normalization helper that recursively converts maps to map[string]any and apply it to the whole input map.

Example fix

// before
items := []map[string]string{{"name": "a"}}
m := map[string]any{"items": items} // field is []Item
// after
m := map[string]any{"items": []any{map[string]any{"name": "a"}}}
Defensive patterns

Strategy: type-guard

Validate before calling

for _, e := range items.([]any) {
  if _, ok := e.(map[string]any); !ok {
    return fmt.Errorf("slice elements must be objects (map[string]any)")
  }
}

Type guard

func isStringAnyMapSlice(v any) bool {
  s, ok := v.([]any)
  if !ok { return false }
  for _, e := range s {
    if _, ok := e.(map[string]any); !ok { return false }
  }
  return true
}

Try / catch

if err := util.AssignMapToStruct(m, &cfg); err != nil {
  if strings.Contains(err.Error(), "cannot assign element of type") {
    log.Fatalf("struct-slice element shape wrong: %v", err)
  }
}

Prevention

When it happens

Trigger: Assigning []any{map[string]string{...}} or []map[string]string{...} to a field of type []SomeStruct via AssignMapToStruct.

Common situations: 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.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07). Data as JSON: /api/errors/262456cde694f9c5. Report an issue: GitHub.

Appendix: source

Thrown at util/config.go:1218

					// Build destination slice
					newSlice := reflect.MakeSlice(fieldValue.Type(), 0, sourceSlice.Len())
					for i := 0; i < sourceSlice.Len(); i++ {
						srcElemVal := sourceSlice.Index(i)
						// When source is []any, elements come as interface{}, unwrap reflect.Value
						if srcElemVal.Kind() == reflect.Interface && !srcElemVal.IsNil() {
							srcElemVal = reflect.ValueOf(srcElemVal.Interface())
						}

						var dstElem reflect.Value
						// Prepare destination element
						if fieldElemType.Kind() == reflect.Struct {
							dstElem = reflect.New(fieldElemType).Elem()
							if srcElemVal.Kind() == reflect.Map {
								// Expect map[string]any
								mIface, ok := srcElemVal.Interface().(map[string]any)
								if !ok {
									return fmt.Errorf("cannot assign element of type %T to slice element of type %s", srcElemVal.Interface(), fieldElemType)
								}
								if err := assignMapToStructRecursive(mIface, dstElem); err != nil {
									return err
								}
							} else if srcElemVal.Type().ConvertibleTo(fieldElemType) {
								dstElem = srcElemVal.Convert(fieldElemType)
							} else {
								return fmt.Errorf("cannot assign element of type %s to slice element of type %s", srcElemVal.Type(), fieldElemType)
							}
						} else {
							// Primitive or other kinds
							if srcElemVal.Type().ConvertibleTo(fieldElemType) {
								dstElem = srcElemVal.Convert(fieldElemType)
							} else {
								newVal, converted := CastValueToKind(srcElemVal.Interface(), fieldElemType.Kind())
								if !converted {
									return fmt.Errorf("cannot assign element of type %s to slice element of type %s", srcElemVal.Type(), fieldElemType)
								}

View on GitHub (pinned to 1774ccb71a)