How to fix Viper unmarshal error for nested structs

close up shot of a toy

Let’s say you have the following structs that you need to unmarshal using Go’s Viper library (Go configuration with fangs).

// Level 2; Struct for the top-level service configuration
type ServiceConfig struct {
	BaseURL string `yaml:"base_url"`
	APIKey  string `yaml:"api_key"`
}

// Level 2; Struct for the providers configuration, with nested structs
type ProvidersConfig struct {
	Payment struct {
		Dwolla struct {
			BaseURL string `yaml:"base_url"`
			APIKey  string `yaml:"api_key"`
		} `yaml:"dwolla"`
	} `yaml:"payment"`
}

// Level 1; struct to hold the entire config
type Config struct {
	Service   ServiceConfig   `yaml:"service"`
	Providers ProvidersConfig `yaml:"providers"`
}

It’s intended to parse the configuration file you have found on config.yaml on your root folder, which looks something like this:

service:
  base_url: https://api.yourwebsite.com/v1
  api_key: some_api_key
providers:
  payment:
    dwolla:
      base_url: https://sandbox.api.dwolla.com
      api_key: some_api_key

Symptom or Problem

Sometimes you encounter unmarshalling errors when using viper.Unmarshal, or sometimes there is no error or warning message at all- the struct simply does not get its field values parsed.

Root cause

When encoding or decoding data, Go uses metadata found on the struct tags to determine how to unmarshal or marshal fields within a struct (e.g. using encoding formats like JSON or YAML). The yaml struct tag is useful when the config file you are parsing is being parsed with only a single level (e.g. all of your fields are parsed into a single struct found on Level 1, as labeled above, without any Level 2 structs). However, sometimes you already have existing struct definitions that you want to reuse instead of introducing redundancies through duplicate fields.

Solution

If your config file is a single level struct, then there won’t be any problems using the yaml Golang structural flag. However, if your config file uses multiple-level structs as in the case of providers, then you need to use mapstructure instead of yaml when defining your structs.

As shown in the example above, there are multiple levels of structs under providers (i.e. payment contains Dwolla). The different with service is that its fields are set only in one level.

Reproducible example

  • Replit example (Go 1.21)
    • You can find valid/main.go for the correct implementation using mapstructure.
    • You can find invalid/main.go for the implementation that doesn’t throw an error, but proceeds execution without properly parsing the config file (leaving it empty).

References

Keywords

  • Go struct not unmarshalling YAML
  • Nested YAML not parsing in Go
  • Go struct parsing issues with Viper
  • YAML config file not working in Go
  • Viper mapstructure nested structs
  • Viper cannot unmarshal nested YAML
  • Go Viper config unmarshal error
  • YAML nested structs in Go not working
  • Go Viper not parsing nested config
  • Viper not loading nested YAML
  • “Go struct not being parsed correctly”
  • “Unmarshal Go YAML config file not working”
  • “Viper config not populating Go struct”
  • “Go mapstructure nested config issue”
  • “YAML nested structure error in Go”
  • “Viper struct unmarshal nested error”
  • “Nested structs not loading in Go”
  • “Viper cannot parse multiple-level YAML”
  • “Mapstructure not decoding nested YAML”
  • “Viper not decoding YAML into struct”
  • “Error unmarshaling Go struct with nested YAML”
  • “Go YAML config file nested struct parsing issue”
  • “Cannot unmarshal nested YAML into Go struct”
  • “Why isn’t my YAML file populating Go struct?”
  • “Viper failing to unmarshal nested YAML structure”
  • “Go struct unmarshalling failure in nested config”
  • “Incorrect field mapping in Go nested YAML”
  • “Mapstructure decoding error with nested structs”
  • “Go Viper YAML parsing not working”
  • “Go nested struct configuration errors in YAML”

2 responses to “How to fix Viper unmarshal error for nested structs”

  1. tables Avatar

    Thanks foг sharing your info. I truly appreⅽiate your efforts and I will be
    waiting for your neҳt post thank you once again.

    1. darrensapalo Avatar

      You’re welcome! Let me know if you have any questions or need any help.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.