kataras/iris · error

unsupported type: %T

Error message

unsupported type: %T

What it means

This is the outer default branch of AllowUsers: it panics when the `users` argument is neither a slice nor a recognized map type after reflect unwrapping. The library only supports the documented forms (map[string]string, map[string]any, []map[string]any, []User-like structs), so anything else is rejected at startup.

Source

Thrown at middleware/basicauth/user.go:131

		elem := v.Interface()
		switch m := elem.(type) {
		case map[string]string:
			return userMap(m, opts...)
		case map[string]any:
			username, password, ok := mapUsernameAndPassword(m)
			if !ok {
				break
			}

			cp[username] = &user{
				password: password,
				ref:      m,
			}
		default:
			panic(fmt.Sprintf("unsupported type of map: %T", users))
		}
	default:
		panic(fmt.Sprintf("unsupported type: %T", users))
	}

	options := toUserAuthOptions(opts)

	return func(_ *context.Context, username, password string) (any, bool) {
		if u, ok := cp[username]; ok { // fast map access,
			if options.ComparePassword(u.password, password) {
				return u.ref, true
			}
		}

		return nil, false
	}
}

func userMap(usernamePassword map[string]string, opts ...UserAuthOption) AuthFunc {
	options := toUserAuthOptions(opts)

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Ensure the argument is non-nil and is one of: map[string]string, map[string]any, or a slice of users/structs.
  2. Wrap a single user struct in a slice: AllowUsers([]MyUser{u}).
  3. Check that the config value feeding AllowUsers was actually decoded (log %T of the value before calling).

Example fix

// before
basicauth.AllowUsers(nil)
// after
if users == nil {
    log.Fatal("no users configured")
}
basicauth.AllowUsers(users) // map[string]string, map[string]any, or slice
Defensive patterns

Strategy: validation

Validate before calling

if users == nil {
    return errors.New("basicauth: users must not be nil")
}
rv := reflect.Indirect(reflect.ValueOf(users))
if rv.Kind() != reflect.Slice && rv.Kind() != reflect.Map {
    return fmt.Errorf("basicauth: users must be slice or map, got %T", users)
}

Type guard

func isAllowUsersInput(v any) bool {
    if v == nil { return false }
    k := reflect.Indirect(reflect.ValueOf(v)).Kind()
    return k == reflect.Slice || k == reflect.Map
}

Try / catch

// construction-time panic; validate before:
if !isAllowUsersInput(users) { log.Fatalf("invalid basicauth users input %T", users) }
opts.Allow = basicauth.AllowUsers(users)

Prevention

When it happens

Trigger: Calling AllowUsers(nil), AllowUsers("user:pass"), AllowUsers(someStruct{}) (a single struct, not a slice), or AllowUsers(&notASliceOfUsers). A nil pointer to a slice passes reflect.Indirect but a nil untyped argument does not match any case.

Common situations: Passing nil because the users variable was never loaded; passing one user struct instead of a slice; passing a JSON-decoded value typed as any that turned out to be a string or number.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/dcf853ed6c554de9. Report an issue: GitHub.