Viper: When key is nested, config file value not override default value

Created on 8 Feb 2017  路  5Comments  路  Source: spf13/viper

Set default value in init method using viper.SetDefault("peer.gossip.orgLeader", "xxx"), and use config file value "yyy" to override "xxx" in main method. After that, viper.GetBool("peer.gossip.orgLeader"), the value still "xxx". However, it works fine when key is "orgLeader".

Most helpful comment

Also broken with env var overrides:

main.go:

package main

import (
    "fmt"
    "github.com/spf13/viper"
)

type Config struct {
    MyKey string `json:"mykey,omitempty"`
}

func main() {
    config := &Config{}

    viper.BindEnv("mykey", "MY_KEY")
    viper.SetConfigFile("./config.json")
    viper.ReadInConfig()
    viper.UnmarshalKey("subcfg", config)

    fmt.Println("Value of mykey:", config.MyKey)
}

config.json:

{
  "subcfg": {
    "mykey": "value in config.json"
  }
}

Produces:

$ MY_KEY="value in env var" go run main.go
Value of mykey: value in config.json

All 5 comments

Confirmed

fmt.Println(viper.AllSettings())
fmt.Println(viper.Get("mongo"))
map[mongo:map[db:new_db hosts:172.17.0.2] server:map[address:127.0.0.1:5050]]
map[hosts:172.17.0.2 db:test_db]

AllSettings method returns the correct result.

Hm...
Nested maps was always broken.
ec4eb2f

config := ServerConfig{}
viper.UnmarshalKey("mongo", &config)
fmt.Println(viper.AllKeys())
fmt.Println(viper.AllSettings())
fmt.Println(viper.Get("mongo"))
fmt.Println(config.MongoDBName)
[mongo.hosts mongo.db server.address]
map[server:map[address:127.0.0.1:5050] mongo:map[hosts:172.17.0.2 db:new_db]] // new value
map[hosts:172.17.0.2 db:test_db] // default value
test_db // default value

Also broken with env var overrides:

main.go:

package main

import (
    "fmt"
    "github.com/spf13/viper"
)

type Config struct {
    MyKey string `json:"mykey,omitempty"`
}

func main() {
    config := &Config{}

    viper.BindEnv("mykey", "MY_KEY")
    viper.SetConfigFile("./config.json")
    viper.ReadInConfig()
    viper.UnmarshalKey("subcfg", config)

    fmt.Println("Value of mykey:", config.MyKey)
}

config.json:

{
  "subcfg": {
    "mykey": "value in config.json"
  }
}

Produces:

$ MY_KEY="value in env var" go run main.go
Value of mykey: value in config.json

Still not fixed?

798

// fix: https://github.com/spf13/viper/issues/798
for _, key := range viper.AllKeys() {
    viper.Set(key, viper.Get(key))
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

aarondl picture aarondl  路  6Comments

lllama picture lllama  路  3Comments

gmaxwell94 picture gmaxwell94  路  5Comments

jeffwillette picture jeffwillette  路  5Comments

michaeleekk picture michaeleekk  路  3Comments