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
- Invoke through `uniond testnet` so the operator-address flag is registered and defaults bind
- Programmatically: viper.Set(server.KeyNewOpAddr, "union1...") with an actual string value
- Verify the option source — viper keys are lowercase; a casing mismatch yields nil
- 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
- Bind testnet flags via the standard command so defaults exist
- Use lowercase viper keys — casing mismatches yield nil and trip the assertion
- Avoid sourcing these options from JSON where types degrade to floats/objects
- In forks, prefer returning an error naming the missing key
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
- newValAddr is not of type bytes.HexBytes
- newValPubKey is not of type crypto.PubKey
- upgradeToTrigger is not of type string
- error while incrementing period: %w
- error while creating a new delegation period record: %w
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/ac72e22dea0a716c.
Report an issue: GitHub.