#1071·yaml

leading spaces in multiline string: marshal/unmarshal fails

Author: viktorasmCreated Mar 15, 2025Updated Mar 15, 2025

In specific combination of list item and leading spaces in string value, this results in an unparseable result:

go
func TestLoadYaml(t *testing.T) {
	r := require.New(t)

	type Params struct {
		Description string `yaml:"description"`
	}
	type Spec struct {
		Parameters []Params `yaml:"parameters"`
	}
	spec := Spec{
		Parameters: []Params{
			{
				Description: "  a\nb",
			},
		},
	}

	marshalledContents, err := yaml.Marshal(&spec)
	r.NoError(err)
	r.NoError(yaml.Unmarshal(marshalledContents, &spec))
}

If Marshalling with encoder indent forced to 1, then test passes:

go
func TestLoadYaml(t *testing.T) {
	r := require.New(t)

	type Params struct {
		Description string `yaml:"description"`
	}
	type Spec struct {
		Parameters []Params `yaml:"parameters"`
	}
	spec := Spec{
		Parameters: []Params{
			{
				Description: "     a\nb",
			},
			{
				Description: " a\n      b",
			},
		},
	}

	buf := new(bytes.Buffer)
	enc := yaml.NewEncoder(buf)
	enc.SetIndent(1)
	r.NoError(enc.Encode(&spec))

	var unmarshalledSpec Spec
	r.NoError(yaml.Unmarshal(buf.Bytes(), &unmarshalledSpec))
	r.Equal(spec, unmarshalledSpec)
}