go-kratos/kratos · error

type assert to %v failed

Error message

type assert to %v failed

What it means

config.Value is backed by an atomic.Value; typed accessors (Bool, Int, Float, Duration, ...) try a direct type switch plus string/number conversions, and when none apply they return this error naming the actually stored type. It means the config value's runtime type does not fit the requested accessor.

Source

Thrown at config/value.go:39

type Value interface {
	Bool() (bool, error)
	Int() (int64, error)
	Float() (float64, error)
	String() (string, error)
	Duration() (time.Duration, error)
	Slice() ([]Value, error)
	Map() (map[string]Value, error)
	Scan(any) error
	Load() any
	Store(any)
}

type atomicValue struct {
	atomic.Value
}

func (v *atomicValue) typeAssertError() error {
	return fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load()))
}

func (v *atomicValue) Bool() (bool, error) {
	switch val := v.Load().(type) {
	case bool:
		return val, nil
	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64:
		return strconv.ParseBool(fmt.Sprint(val))
	case string:
		return strconv.ParseBool(val)
	}
	return false, v.typeAssertError()
}

func (v *atomicValue) Int() (int64, error) {
	switch val := v.Load().(type) {
	case int:
		return int64(val), nil

View on GitHub (pinned to 668db92c2c)

Solutions

  1. Inspect the raw value with v.Load() (the error already prints the real type via %T)
  2. Fix the config so the value matches the accessor (unquote numbers, use true/false for booleans)
  3. Prefer Value.Scan into typed structs over scalar accessors

Example fix

// before
port := c.Value("data.database.port").Int() // underlying is string "3306"

// after
port, err := strconv.Atoi(c.Value("data.database.port").String())
// or fix the config to an unquoted number: port: 3306
Defensive patterns

Strategy: type-guard

Type guard

func isBoolLike(v config.Value) bool {
    switch v.Load().(type) {
    case bool, int, int64, float64, string:
        return true
    }
    return false
}

Try / catch

b, err := v.Bool()
if err != nil {
    if strings.Contains(err.Error(), "type assert") {
        // wrong underlying type: inspect v.Load() and fix the config
        return handleTypeMismatch(v.Load())
    }
    return err
}

Prevention

When it happens

Trigger: Calling a typed accessor on a config Value whose stored type does not match — Bool() on a map or slice, Int() on a list, Duration() on a non-string, or after Store() of an arbitrary type.

Common situations: Numbers or booleans quoted as strings after env overrides; accessing a tree node (always a map) with a scalar accessor; config schema drift between environments.

Related errors


AI-assisted analysis of go-kratos/kratos@668db92c2c (2026-08-16). Data as JSON: /api/errors/f278860ac3c5ffe7. Report an issue: GitHub.