Errors¶
Every failure the package returns wraps a sentinel built with the estate's
errors module, so errors.Is matches it and the stack behind it is
available with %+v. Sentinels raised inside the engine's layers are
re-exported under one name each, so a caller matches ErrKind whether the
schema or the number conversion saw the mismatch.
Reading and addressing¶
| Sentinel | Means | Do |
|---|---|---|
ErrNotFound |
A step or path does not resolve, or a sequence index is past the end | Check the key; RemoveIfPresent if absence is fine |
ErrKind |
The node is not the kind the operation needs: Int64 on a string, Entries on a scalar, a path running through a scalar |
Inspect with Syntax or Value first |
ErrAmbiguous |
Two entries have semantically equal keys and the selection cannot choose | Validate; the document has a duplicate key |
ErrPath |
A dotted path is empty, has an empty segment, or has a malformed bracket: a[, a[], a[-1], a[01], a[1]b, a ] inside a key |
Fix the path |
ErrStep |
A step of the wrong shape, such as IndexStep given to Set |
Use Replace on the selected item |
ErrInvalidIndex |
A negative sequence index | Fix the index |
ErrAlias |
The target is an alias, and the operation needs the anchored node | Go through AliasTarget, or edit under the anchor |
ErrRange, ErrPrecision |
The value does not fit the requested Go type without loss | Use BigInt, Rat or Number |
ErrContent |
A scalar's text is not valid for its tag, such as !!int nope |
Validate; the document is wrong |
ErrResolution |
A plain scalar matches nothing in the selected schema, such as yes under JSON; every typed read of it says so |
Choose a profile that does, or quote it |
ErrUnresolved |
The profile leaves the node's non-specific tag unresolved, as Failsafe does for every plain scalar | Read it with Raw or Syntax, or choose another profile |
ErrTimestamp, ErrBinary |
A !!timestamp or !!binary whose text is not a valid value, such as 1900-02-29 or Zh==; it is also ErrContent |
Validate; the document is wrong |
ErrUnsupportedType |
The selected profile has no such type | Choose a profile that does, or tag explicitly |
ErrView |
A zero Node, or a view whose revision has been released |
Take a fresh snapshot |
ErrExpired |
A working view used after its callback returned | Read inside the callback, or from a committed snapshot |
Parsing and validation¶
| Sentinel | Means |
|---|---|
ErrSyntax |
The bytes are not YAML under the selected language, including a bad escape or an unterminated quote |
ErrEncoding |
The bytes are not valid in their encoding, such as a stray 0xff in UTF-8, or the encoding is one the document's YAML version does not admit |
ErrUnsupportedVersion |
A %YAML directive names a version the engine does not implement; only 1.1 and 1.2 are |
ErrVersionConflict |
A directive disagrees with Options.Version |
ErrProfile |
A profile combination outside the built-in inventory, or one that does not match its document's version |
ErrOptions |
An Options value with a negative limit or an invalid profile |
ErrSemantic |
The document has invalid or unavailable semantic content; Validate lists it |
ErrDanglingAlias |
An alias with no prior anchor in its document |
ErrDuplicateKey |
A mapping with two semantically equal keys |
ErrCollectionContent |
A !!set, !!omap or !!pairs whose members do not have that structure, such as a set entry with a value |
Parse also returns a *ParseFailure when the syntax parsed but the
requested profiles could not be admitted; it carries the bytes for inspection,
so a caller can show the file, or hand it to a lenient reader, without
holding a second copy.
Merging and projecting¶
| Sentinel | Means |
|---|---|
ErrMergeUnsupported |
EvaluateMerge under a profile without merge support |
ErrMergeSource |
A << source that is not a mapping or a sequence of mappings |
ErrMergeCycle |
A merge source that inherits from its own receiver |
ErrProjectionAlias |
Project met an alias and was not asked to expand it |
ErrProjectionCycle |
Expanding the aliases would not terminate |
ErrStringKey |
Project met a mapping key that is not a resolved string |
ErrProjectionType |
A type with no ordinary Go container, such as !!set |
Resource limits¶
Each limit struct in Options.Limits has its own sentinel, so the error says
which budget to raise. A zero limit takes its default from DefaultLimits.
| Sentinel | Budget |
|---|---|
ErrSyntaxLimit |
SyntaxLimits while parsing, and RevisionLimits.Bytes, Nodes and Work during an edit |
ErrComposeLimit |
ComposeLimits, or ProjectionLimits in Project |
ErrScalarLimit, ErrNumberLimit |
ScalarLimits, joined with ErrComposeLimit for a document's scalar and ErrInputLimit for a written one; ErrNumberLimit alone from BigIntKey |
ErrCommentLimit |
CommentLimits |
ErrGraphLimit |
GraphLimits, in Key.Equal, Detach and write input |
ErrPatchLimit, ErrExpectedLimit |
PatchLimits and ExpectedLimits in a transaction |
ErrMergeLimit |
The MergeLimits given to EvaluateMerge |
Editing¶
| Sentinel | Means | Do |
|---|---|---|
ErrExists |
Insert named a mapping key that is already there |
Use Set |
ErrDocumentExists |
CreateDocument on a stream that has one |
Edit the document instead |
ErrReference |
The edit would remove an anchor a surviving alias still needs | Change the alias first |
ErrTagIntent |
The value would change the node's explicit tag, which needs explicit intent | Replace the node with a tagged value, or leave the tag |
ErrPresentation |
The requested presentation cannot represent the value, no presentation was found that keeps every retained comment, or the value cannot be written as JSON inside a JSON-style flow collection | Address a smaller node, or write a value JSON can hold |
ErrMismatch |
The re-parsed candidate did not match the independent statement of the edit; nothing was committed | Report it: this is a bug in the engine, and the file is intact |
ErrPreservation |
The edit would change bytes a retained dependency needs | As above |
ErrCommand |
A command is incomplete or contradicts itself: a comment copy or move with no destination, or one comment moved to two places | Name a destination, or split the request |
ErrPlacement |
A comment destination the source cannot express with the requested owner, two comment groups for one place, or an anchor that moves | Send ordered commands, or choose another owner or anchor |
ErrStale |
A Node, Comment or CommentOwner from a previous working revision was given to a command |
Select again from tx.Snapshot() |
ErrActiveTransaction |
A second Edit, or a helper such as Document.Set, while one is open |
Use the open transaction |
ErrCallback |
The callback panicked; the panic was recovered and the transaction discarded | Fix the callback |
ErrEditLimit, ErrInputLimit |
A transaction or write input exhausted its resource limit | Raise the limit in Options, or split the batch |
ErrInternal |
A panic inside the engine, recovered; nothing was committed | Report it with the input |
A *CommentPreservationFailure wraps ErrPreservation when the failing
dependency is a comment, and names the original occurrence and, where there
is one, the candidate that no longer matches: the report says which comment
moved, not only that one did.
A value that cannot be written (an unsupported Go type, a map key that
cannot be a YAML key, a cycle through a pointer or container) comes back as
an *InputFault carrying the path into your input as typed steps:
x[1] is [{Key: "x"}, {Index: 1, IsIndex: true}]. The path is kept
structurally rather than formatted, and the offending value is never passed
through String() or %v, so a secret in a struct does not reach the error
text.
Messages¶
Sentinel messages are stable prose, such as selection does not exist, and
the wrapping carries the stack rather than repeating the message. Match on the
sentinel, not the text.