Validate a YAML file and say exactly what’s wrong and where. oneyaml’s errors are typed: match them with errors.As and read the position from their fields.
package main import ( "errors" "fmt" oneyaml "oneyaml.dev/go" ) type Config struct { Port uint16 `yaml:"port"` Debug bool `yaml:"debug"` Workers int `yaml:"workers"` } func main() { // Malformed YAML: a *SyntaxError with a line, a column and a category. err := oneyaml.Unmarshal([]byte("name: web\nports: [80, 443\n"), new(any)) var se *oneyaml.SyntaxError if errors.As(err, &se) { fmt.Printf("%d:%d %s: %s\n", se.Line, se.Column, se.Category, se.Msg) } // A duplicate key says where the first one was. err = oneyaml.Unmarshal([]byte("name: web\nname: api\n"), new(any)) if errors.As(err, &se) { fmt.Printf("%d:%d %q, first at %d:%d\n", se.Line, se.Column, se.Key, se.FirstLine, se.FirstColumn) } // Values that don't fit: every mismatch, each with its path and position. var cfg Config err = oneyaml.Unmarshal([]byte("port: 99999\ndebug: yes\nworkers: 4\n"), &cfg) var te *oneyaml.TypeError if errors.As(err, &te) { for _, e := range te.All() { fmt.Printf("%d:%d %s: %s\n", e.Line, e.Column, e.Path, e.Msg) } } fmt.Println("the rest is still read: workers =", cfg.Workers) }
3:1 syntax: expected ',' or ']' after an entry of the flow sequence opened at line 2, column 8 (is its closing ']' missing?) 2:1 "name", first at 1:1 1:7 /port: value `99999` overflows uint16 2:8 /debug: cannot unmarshal !!str `yes` into bool the rest is still read: workers = 4
Good to know
*SyntaxErroris YAML that isn’t well formed.LineandColumnare 1-based, counted in characters;Offsetis the byte offset. Switch onCategory, not onMsg.- For a duplicate key,
Key,FirstLineandFirstColumnsay which key and where it first appeared. - A type mismatch doesn’t stop the read. The value that doesn’t fit is skipped and the rest is read. The
*TypeErrordescribes the first mismatch andAll()lists every one, each with an RFC 6901Path. - Limit errors are a
*LimitErrornaming theLimitthat was hit (read untrusted YAML safely). Every error matches its sentinel witherrors.Is:ErrSyntax,ErrLimit,ErrNotFoundand the others. - Error messages are written for people and may change in a minor release. Match errors by type, sentinel and constant.