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¶
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¶
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¶
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¶
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¶
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:
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.