unionlabs/union · error

newOperatorAddress is not of type string

Error message

newOperatorAddress is not of type string

What it means

getCommandArgs asserts that appOpts.Get(server.KeyNewOpAddr) yields a Go string (the new validator operator's bech32 address). If the option is absent (nil) or stored as another type, the assertion fails and the process panics during testnet setup.

Source

Thrown at uniond/cmd/uniond/cmd/testnet.go:231

}

// parse the input flags and returns valArgs
func getCommandArgs(appOpts servertypes.AppOptions) (valArgs, error) {
	args := valArgs{}

	newValAddr, ok := appOpts.Get(server.KeyNewValAddr).(bytes.HexBytes)
	if !ok {
		panic("newValAddr is not of type bytes.HexBytes")
	}
	args.newValAddr = newValAddr
	newValPubKey, ok := appOpts.Get(server.KeyUserPubKey).(crypto.PubKey)
	if !ok {
		panic("newValPubKey is not of type crypto.PubKey")
	}
	args.newValPubKey = newValPubKey
	newOperatorAddress, ok := appOpts.Get(server.KeyNewOpAddr).(string)
	if !ok {
		panic("newOperatorAddress is not of type string")
	}
	args.newOperatorAddress = newOperatorAddress
	upgradeToTrigger, ok := appOpts.Get(server.KeyTriggerTestnetUpgrade).(string)
	if !ok {
		panic("upgradeToTrigger is not of type string")
	}
	args.upgradeToTrigger = upgradeToTrigger

	// validate  and set accounts to fund
	accountsString := cast.ToString(appOpts.Get(flagAccountsToFund))

	for _, account := range strings.Split(accountsString, ",") {
		if account != "" {
			addr, err := sdk.AccAddressFromBech32(account)
			if err != nil {
				return args, fmt.Errorf("invalid bech32 address format %w", err)
			}
			args.accountsToFund = append(args.accountsToFund, addr)

View on GitHub (pinned to 031785bb6d)

Solutions

  1. Invoke through `uniond testnet` so the operator-address flag is registered and defaults bind
  2. Programmatically: viper.Set(server.KeyNewOpAddr, "union1...") with an actual string value
  3. Verify the option source — viper keys are lowercase; a casing mismatch yields nil
  4. In a fork, convert these panics into returned errors for embeddability
Defensive patterns

Strategy: type-guard

Validate before calling

vpr.Set(server.KeyNewOpAddr, "union1operator...") // must be a Go string, present even if only a default

Type guard

func optString(appOpts servertypes.AppOptions, key string) (string, bool) {
	v, ok := appOpts.Get(key).(string)
	return v, ok
}

Prevention

When it happens

Trigger: Building the testnet app in-process without setting server.KeyNewOpAddr; a wrapper command that does not bind the flag into viper; the option loaded from a structured config file into a non-string JSON type.

Common situations: Test harnesses and custom tooling invoking the app builder; refactors of the testnet command flags; configs where the value deserializes as a number or nested object.

Related errors


AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16). Data as JSON: /api/errors/ac72e22dea0a716c. Report an issue: GitHub.