Skip to content

Errors

Five sentinels, matched with errors.Is. Every error the library returns wraps one of them — except the error from Parse, which is the parser's own.

switch {
case errors.Is(err, yamldoc.ErrNotFound):     // the path is not there
case errors.Is(err, yamldoc.ErrInvalidPath):  // the path is malformed
case errors.Is(err, yamldoc.ErrUnsupported):  // the document forbids this edit
case errors.Is(err, yamldoc.ErrEmitInvalid):  // emission would produce broken YAML
case errors.Is(err, yamldoc.ErrInternal):     // a bug in the library
}

Every message begins yamldoc:, so an error surfaced to a user says where it came from.

ErrNotFound

yamldoc: path not found

Returned by Set and Remove. Get and Keys report the same conditions as a false second return rather than an error.

Three distinct causes, distinguishable by the message:

Message Cause What to do
path not found: server.port Remove on a path that does not resolve Check the key name. Removing an absent key is an error, not a no-op, because silence there hides typos
path not found: document root is *ast.SequenceNode, not a mapping The document's root is a sequence, a scalar, a comment group, or empty This library addresses mapping keys. A document with no root mapping cannot be edited at all
path not found: "a" is not a mapping, so the remaining path cannot be created An intermediate segment exists but holds a scalar or a sequence Creating the rest of the path would mean destroying a. Set a to a mapping deliberately if that is what you meant

ErrInvalidPath

yamldoc: invalid path

The path expression itself is malformed, before any lookup happens.

Message Input
invalid path: empty "" or whitespace, passed to Get, Set or Remove
invalid path: "a..b" has an empty segment a doubled dot
invalid path: "a." has an empty segment a trailing dot

Keys("") is not an error — an empty path there means the document root.

ErrUnsupported

yamldoc: document contains an unsupported construct

The document, or the edit, cannot be carried out without corrupting something. Four sites return it.

From Bytes, because the source contains an unsupported construct.

yamldoc: document contains an unsupported construct: line 12: multi-line flow
collection with interior comments (collection spans lines 12-15)

Nothing is emitted. Check File.Unsupported after parsing rather than discovering this after the caller has made their edits — see Unsupported constructs.

From Set, on a path whose value is an alias.

yamldoc: document contains an unsupported construct: "use" is an alias; edit the
anchor definition instead

Writing through *name cannot say whether you mean the shared value or just this use of it, so it refuses rather than guessing. Address the &name definition.

From Set or Remove, when the edit would orphan an alias.

yamldoc: document contains an unsupported construct: removing "base" would leave
alias *b at "child.<<" dangling

The path being removed or replaced defines an anchor that something else still references. The message names the first alias that would break, by path, so you can decide whether to remove that too.

From Set, on a mapping view that is not part of the document.

yamldoc: document contains an unsupported construct: cannot write through a
single-entry mapping view

A guard: some mapping shapes have to be wrapped to be walked, and a write through the wrapper would be discarded silently. Refusing is the only honest outcome. No input observed against goccy/go-yaml v1.19.2 produces this shape, so seeing it is worth reporting.

ErrEmitInvalid

yamldoc: refusing to emit invalid YAML

Returned by Bytes when the re-emitted document does not parse, or parses but does not decode. The wrapped error is the parser's, with the offending line:

yamldoc: refusing to emit invalid YAML: [1:4] mapping value is not allowed in this
context
>  1 | a: key: value
          ^

No bytes are returned. Nothing was written and nothing was damaged — the check exists precisely so a bug here cannot reach a file.

In practice you will hit this by assigning a string whose text is YAML syntax over an existing plain scalar: "key: value", "- item", "*alias", or a multi-line string over a numeric or boolean key. See Assigning a string that needs quoting. Anything else reaching this error is a defect worth reporting.

ErrInternal

yamldoc: internal invariant violated

A shape the library builds for itself did not come back the way it was built. It is never the caller's fault. Report it with the input that produced it.

Parse errors are not sentinels

Parse wraps the parser's error rather than one of these:

yamldoc: parse: [2:1] mapping key "a" already defined at [1:1]
   1 | a: 1
>  2 | a: 2
       ^

errors.Is against any yamldoc sentinel is false for it. Treat a non-nil error from Parse as "these bytes are not YAML I can work with" and show the message — it carries the line, the column and a caret, which is more useful to a user than any classification this library could add.