Optionalsuccess: booleanOptionalmessage: stringOptionaltype: "delete" | "create" | "update"Timestamp when the operation ended
OptionalErrorOptional, a structured error object with additional information
OptionalErrorsOptional, a list of structured error objects with additional information
A message for an end user
A copy of the values of the entity object AFTER the operation was performed
A copy of the values of the entity object BEFORE the operation was performed
Timestamp when the operation started
True if successful, false otherwise
The type of operation that was performed
Returns a complete message that includes the Message property (if present), the Error property (if present), and any Errors array items (if present).
StaticErrorRenders ONE entry of the Errors array as human-readable text.
Errors is typed any[], and two shapes land in it from different places:
ValidationErrorInfo — carries Message (capital M), plus Source, Value and
Type. This is what _InnerSave puts there when validation refuses a save: it throws the
ValidationResult, and the catch block assigns newResult.Errors = e.Errors.Error (and anything error-like) — carries lowercase message.This used to read err.message ONLY, so every ValidationErrorInfo fell through to
JSON.stringify(err). That is not a cosmetic difference: CompleteMessage is the string the
server hands the client on a failed save — every write-refusal throw in ResolverBase
(CreateRecord/UpdateRecord/DeleteRecord) puts it in the GraphQLError, and
SaveEntityGraphOperation puts it in ErrorMessage — so the whole point of writing a careful,
field-named refusal in a subclass's ValidateAsync() was defeated at the last step, and the
user saw
{"Source":"ParentContractID","Message":"…","Value":null,"Type":"Failure"} in a toast.
Nothing catches this at compile time because Errors is any[]; nothing catches it at runtime
because JSON.stringify always succeeds. It is only visible by reading the message a user got.
The parameter is unknown rather than any — per .claude/rules/typescript-style.md — because
not knowing the shape is the whole reason this helper exists, and unknown forces the narrowing
that makes each shape's handling explicit. Callers pass any (the Errors array and the Error
property are both legacy any), which is assignable, so no call site changes.
Message is preferred over message because a ValidationErrorInfo has only the former,
while an Error has only the latter — so the order matters solely for an object carrying both,
where the MJ-native field is the better answer.
One entry from the Errors array.
The entry's human-readable text, falling back to JSON for a shape with neither field.
Used for storing the result of a Save or Delete or other transactional operation within a BaseEntity