wavetermdev/waveterm · error

invalid value type for %s: %T

Error message

invalid value type for %s: %T

What it means

SetBaseConfigValue compares reflect.TypeOf(val) against the key's registered type; if they differ and the declared type is not a pointer wrapper of the value's type, it returns 'invalid value type for %s: %T'. Only exact Go type matches (or pointer-wrappable) values are accepted.

Source

Thrown at pkg/wconfig/settingsconfig.go:874

			return fmt.Errorf("invalid config key: %s", configKey)
		}
		if val == nil {
			delete(m, configKey)
		} else {
			rtype := reflect.TypeOf(val)
			if rtype == reflect.TypeOf(dummyNumber) {
				convertedVal, err := convertJsonNumber(val.(json.Number), ctype)
				if err != nil {
					return fmt.Errorf("cannot convert %s: %v", configKey, err)
				}
				val = convertedVal
				rtype = reflect.TypeOf(val)
			}
			if rtype != ctype {
				if ctype == reflect.PointerTo(rtype) {
					m[configKey] = &val
				} else {
					return fmt.Errorf("invalid value type for %s: %T", configKey, val)
				}
			}
			m[configKey] = val
		}
	}
	return WriteWaveHomeConfigFile(SettingsFile, m)
}

func SetConnectionsConfigValue(connName string, toMerge waveobj.MetaMapType) error {
	m, cerrs := ReadWaveHomeConfigFile(ConnectionsFile)
	if len(cerrs) > 0 {
		return fmt.Errorf("error reading config file: %v", cerrs[0])
	}
	if m == nil {
		m = make(waveobj.MetaMapType)
	}
	connData := m.GetMap(connName)
	if connData == nil {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Convert the value to the exact declared Go type before calling (e.g. int64(14), float64(0.5))
  2. Look up the key's type via getConfigKeyType or the generated meta constants
  3. Avoid raw json.Number; decode into the concrete type first

Example fix

// before
wconfig.SetBaseConfigValue(waveobj.MetaMapType{"term:fontsize": 14}) // int, wants float64
// after
wconfig.SetBaseConfigValue(waveobj.MetaMapType{"term:fontsize": float64(14)})
Defensive patterns

Strategy: type-guard

Validate before calling

// verify the value type matches the key's registered type
ctype := getConfigKeyType(key)
if ctype != nil && reflect.TypeOf(val) != ctype && reflect.TypeOf(val) != ctype.Elem() {
    return fmt.Errorf("key %s expects %s, got %T", key, ctype, val)
}

Type guard

func valueMatchesKeyType(key string, val any) bool {
    ctype := getConfigKeyType(key)
    if ctype == nil { return false }
    rt := reflect.TypeOf(val)
    return rt == ctype || rt == ctype.Elem() || ctype == reflect.PointerTo(rt)
}

Try / catch

if err := wconfig.SetBaseConfigValue(m); err != nil {
    if strings.Contains(err.Error(), "invalid value type for") {
        return fmt.Errorf("convert value to the key's exact Go type: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling SetBaseConfigValue with a value whose Go type does not match the key's declared type — e.g. float64 for an int64 key, string for a bool key, int (not int64) where int64 is declared.

Common situations: Using untyped Go literals (int) against int64-typed keys; sending strings for numeric keys; version drift where a key's type changed.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/de8da6de8bc31a8a. Report an issue: GitHub.