unionlabs/union · error
newValAddr is not of type bytes.HexBytes
Error message
newValAddr is not of type bytes.HexBytes
What it means
getCommandArgs builds testnet arguments from the app options map with Go type assertions. server.KeyNewValAddr must already hold a bytes.HexBytes value; a nil entry (flag never set) or a value of another type fails the assertion and panics. These typed values are normally injected by the testnet command's flag wiring into viper-backed appOpts.
Source
Thrown at uniond/cmd/uniond/cmd/testnet.go:221
if err != nil {
panic(err)
}
err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, account, defaultCoins)
if err != nil {
panic(err)
}
}
return app
}
// 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
View on GitHub (pinned to 031785bb6d)
Solutions
- Run via the real `uniond testnet` CLI so the server flags are registered and bound into appOpts
- When driving programmatically, populate the options first: viper.Set(server.KeyNewValAddr, bytes.HexBytes(...)) plus the other server.Key* values
- Do not set the value from a config file as a string — the assertion requires the concrete bytes.HexBytes type
- If you need an embeddable API, replace the panics in a fork with an error return listing the missing key
Example fix
// before
newValAddr, ok := appOpts.Get(server.KeyNewValAddr).(bytes.HexBytes)
if !ok {
panic("newValAddr is not of type bytes.HexBytes")
}
// after — populate appOpts with typed values before building the testnet app
vpr := viper.New()
vpr.Set(server.KeyNewValAddr, bytes.HexBytes(valAddrBytes))
vpr.Set(server.KeyUserPubKey, ed25519.PubKey{Key: pubKeyBytes}) // crypto.PubKey value, not a string
vpr.Set(server.KeyNewOpAddr, operatorBech32)
vpr.Set(server.KeyTriggerTestnetUpgrade, "")
vpr.Set("accounts-to-fund", "")
appOpts := servertypes.AppOptions(vpr) Defensive patterns
Strategy: type-guard
Validate before calling
// When driving the testnet app outside the CLI, seed viper with typed values
vpr := viper.New()
vpr.Set(server.KeyNewValAddr, bytes.HexBytes(valAddrBytes))
vpr.Set(server.KeyUserPubKey, ed25519.PubKey{Key: pubKeyBytes})
vpr.Set(server.KeyNewOpAddr, "union1operator...")
vpr.Set(server.KeyTriggerTestnetUpgrade, "")
vpr.Set("accounts-to-fund", "")
appOpts := servertypes.AppOptions(vpr) Type guard
func optHexBytes(appOpts servertypes.AppOptions, key string) (bytes.HexBytes, bool) {
v, ok := appOpts.Get(key).(bytes.HexBytes) // ok is false for nil (missing flag) too
return v, ok
} Prevention
- Prefer the uniond testnet CLI, which binds all server.Key* flags into appOpts
- When embedding, set every option with the exact Go type the assertion expects
- Remember a missing key returns nil, which fails the type assertion just like a wrong type
- Add a regression test that constructs the testnet app with a fully populated appOpts
When it happens
Trigger: Invoking the testnet app-construction path programmatically (tests, embedding, custom commands) without setting server.KeyNewValAddr in appOpts; a modified testnet command that stops binding its flags into viper.
Common situations: In-process tests that build the app the way `uniond testnet` does; wrapping the testnet command in another binary; refactor dropping flag registration so appOpts.Get returns nil.
Related errors
- newValPubKey is not of type crypto.PubKey
- newOperatorAddress is not of type string
- 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/bd69c3bbbfe94f8d.
Report an issue: GitHub.