pub enum ValidationError {
UnknownSection {
key: String,
entity_type: String,
declared: Vec<String>,
suggestion: Option<String>,
},
UnknownMetadata {
key: String,
entity_type: String,
declared: Vec<String>,
suggestion: Option<String>,
},
InvalidEnumValue {
field: String,
value: String,
allowed: Vec<String>,
field_description: Option<String>,
suggestion: Option<String>,
type_write_rules: Vec<String>,
entity_type: String,
},
ReadOnlyField {
field: String,
},
SectionNotUpdatable {
section: String,
entity_type: String,
},
InvalidRelationshipType {
input: String,
allowed: Vec<RelationshipHint>,
suggestion: Option<String>,
},
InvalidRelationshipShape {
rel_type: String,
from_type: String,
to_type: String,
allowed_source_types: Vec<String>,
allowed_target_types: Vec<String>,
suggestion: Option<RelationshipHint>,
},
SectionContentInvalid {
section: String,
embedded_heading: String,
},
SectionContentControlByte {
section: String,
control_char: char,
codepoint: u32,
byte_offset: usize,
},
InvalidFieldValue {
field: String,
value: String,
expected_type: String,
expected_format: Option<String>,
field_description: Option<String>,
entity_type: String,
},
}Expand description
A typed CRUD-time validation failure. Mirrors the wire-format error codes the MCP layer surfaces; the engine adapters convert each variant into their own error type.
Variants§
UnknownSection
UNKNOWN_SECTION: section key not declared on the type and
not absorbed by a catch_all section.
UnknownMetadata
UNKNOWN_METADATA: metadata key not declared on the type.
InvalidEnumValue
INVALID_ENUM_VALUE: enum-typed metadata field rejected the
supplied value.
Fields
ReadOnlyField
READ_ONLY_FIELD: caller tried to set or unset a read-only
metadata key (mem, id, type) on update.
SectionNotUpdatable
SECTION_NOT_UPDATABLE: the section is not in the type’s
updatable_fields allowlist, or it is the virtual
relationships surface (which is managed by memstead_relate,
not memstead_update).
InvalidRelationshipType
INVALID_REL_TYPE: the relationship name is not declared in
the active schema and the schema runs in strict mode. Open-mode
schemas admit unknown names with a warning instead — see
[check_relationship_strict_or_open].
InvalidRelationshipShape
INVALID_REL_SHAPE: the edge’s (from_type, to_type) pair
violates the schema’s declared source_types / target_types
for this relationship. Only fires for shape-pinned edges; an
edge with empty constraint lists admits any pair.
Fields
suggestion: Option<RelationshipHint>SectionContentInvalid
SECTION_CONTENT_INVALID: a section body contains a ^##
line (level-2 heading) which the entity’s compose-then-reparse
pipeline would interpret as a section delimiter. Without this
guard a caller can inject content into a different section by
embedding a heading in another section’s body. Deeper headings
(### and below) are allowed — the parser anchors only on
level 2.
SectionContentControlByte
SECTION_CONTENT_INVALID (control-byte sub-case): a section body
contains a control character other than tab (\t) or newline
(\n). A NUL especially makes git classify the .md blob as
binary, defeating the diffable-markdown invariant the storage
model rests on, and downstream text tooling truncates at it.
Shares the wire code with the heading-injection case (both are
SECTION_CONTENT_INVALID) — the control_char/byte_offset
recovery fields discriminate it from embedded_heading. Mirrors
the title control-char guard (refuse with an actionable hint, not
silent strip). \t and \n stay legal; the verbatim-escape
contract is untouched (this screens a byte class, it does not
de-escape).
Fields
control_char: charThe offending control character (a char, since the body is
already valid UTF-8 — a NUL is U+0000).
InvalidFieldValue
INVALID_FIELD_VALUE: a non-enum typed metadata field received a
value that does not parse as its declared type — a Date field
given "not-a-real-date" or "", or a Number field given
non-numeric text. Distinct from INVALID_ENUM_VALUE (the key and
type are valid but the value is out of an enum’s vocabulary) and
UNKNOWN_METADATA_FIELD (the key is not declared): here the key
and field-type are valid but the value is malformed for the
type. Without this check the value round-trips raw and corrupts
range-filter results (a non-date string sorts lexically against
real dates, so *_after matches it).
Implementations§
Source§impl ValidationError
impl ValidationError
Sourcepub fn code(&self) -> &'static str
pub fn code(&self) -> &'static str
Stable UPPER_SNAKE_CASE wire code for this validation sub-variant.
Single source of truth — both EngineError::code() (via the
Validation(_) arm) and the MCP validation_envelope mapper read
from here, so the wire code cannot drift between channels.
Sourcepub fn details(&self) -> Value
pub fn details(&self) -> Value
Structured recovery payload for this validation sub-variant. The
payload mirrors the variant’s declared fields so callers branching
on code can read the same shape validation_envelope ships on
the MCP wire. Returned shape is documented in the MCP tool
descriptions — see Errors: blocks on memstead_create / memstead_update
/ memstead_relate.
Sourcepub fn prose_render(&self) -> String
pub fn prose_render(&self) -> String
Render rich, fully-inlined recovery prose for the agent-visible
text channel. Closes the asymmetry where warnings render their
structured details inline but errors collapse details.X
references to a “+N more — see details.X” pointer pointing at a
channel the agent’s MCP client doesn’t surface to the model. The
structured
details() channel is unchanged — this method only governs
result.content[0].text. Display stays terse for logs and
tracing::warn! consumers.
Trait Implementations§
Source§impl Clone for ValidationError
impl Clone for ValidationError
Source§fn clone(&self) -> ValidationError
fn clone(&self) -> ValidationError
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ValidationError
impl Debug for ValidationError
Source§impl Display for ValidationError
impl Display for ValidationError
Source§impl Error for ValidationError
impl Error for ValidationError
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl From<ValidationError> for EngineError
impl From<ValidationError> for EngineError
Source§fn from(source: ValidationError) -> Self
fn from(source: ValidationError) -> Self
Auto Trait Implementations§
impl Freeze for ValidationError
impl RefUnwindSafe for ValidationError
impl Send for ValidationError
impl Sync for ValidationError
impl Unpin for ValidationError
impl UnsafeUnpin for ValidationError
impl UnwindSafe for ValidationError
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<T> Fruit for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more