Skip to content

Custom Unmarshaller's receive no data for nested structs #844

@wrouesnel

Description

@wrouesnel

Describe the bug
A clear and concise description of what the bug is.

To Reproduce

package main

import (
	"bytes"
	"fmt"

	"github.com/goccy/go-yaml"
)

type Outside struct {
	X      string `yaml:"x"`
	Inside `yaml:",inline"`
}

type Inside struct {
	Y string `yaml:"y"`
	Z string `yaml:"z"`
}

const data = `x: x-value
y: y-value
z: z-value
`

func main() {
	o := Outside{}

	yaml.RegisterCustomUnmarshaler(func(t *Inside, i []byte) error {
		return yaml.Unmarshal(i, t)
	})

	yaml.NewDecoder(bytes.NewReader([]byte(data))).Decode(&o)
	fmt.Println(o)
}

Please provide a minimum yaml content that can be reproduced.
We are more than happy to use Go Playground

Expected behavior
The above should produce:

{x-value { y-value z-value }}

but instead produces:

{x-value { }}

Version Variables

  • Go version: 1.25.
  • go-yaml's Version: v1.19.2

Additional context

This looks to be a problem with the processing of inline structs which starts here:

go-yaml/decode.go

Line 1382 in 92bc79c

mapNode := ast.Mapping(nil, false)

where a synthetic node map is built without token references, and then when the unmarshal selector logic runs here:

func (d *Decoder) unmarshalableDocument(node ast.Node) ([]byte, error) {

FormatNodeWithResolved alias is called against the synthetic node tree and jumps here:

func FormatNodeWithResolvedAlias(n ast.Node, anchorNodeMap map[string]ast.Node) string {

Which then immediately tries to get the first token, won't find any (because none is set) and returns an empty string instead.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions