Skip to main content

ValidationError

Enum ValidationError 

Source
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,
    },
    EmptyUndeclaredHeading {
        section: String,
        heading: String,
        entity_type: String,
    },
    UnterminatedFence {
        section: String,
        fence: 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.

Fields

§entity_type: String
§declared: Vec<String>
§suggestion: Option<String>
§

UnknownMetadata

UNKNOWN_METADATA: metadata key not declared on the type.

Fields

§entity_type: String
§declared: Vec<String>
§suggestion: Option<String>
§

InvalidEnumValue

INVALID_ENUM_VALUE: enum-typed metadata field rejected the supplied value.

Fields

§field: String
§value: String
§allowed: Vec<String>
§field_description: Option<String>
§suggestion: Option<String>
§type_write_rules: Vec<String>
§entity_type: String
§

ReadOnlyField

READ_ONLY_FIELD: caller tried to set or unset a read-only metadata key (mem, id, type) on update.

Fields

§field: String
§

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).

Fields

§section: String
§entity_type: String
§

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].

Fields

§input: String
§suggestion: Option<String>
§

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

§rel_type: String
§from_type: String
§to_type: String
§allowed_source_types: Vec<String>
§allowed_target_types: Vec<String>
§

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.

Fields

§section: String
§embedded_heading: String
§

EmptyUndeclaredHeading

EMPTY_UNDECLARED_HEADING: caller-supplied content carries a heading the type does not declare with NO body under it (consistency-sweep 04/01, criterion 7). The catch-all builder skips empty content, so such a heading is dropped on the write that accepts it: the caller is told now rather than discovering the loss afterwards.

The boundary is exactly the complement of the catch-all exemption validate_section_content grants: an undeclared heading WITH a body survives verbatim and is accepted, one without a body does not survive and is refused. The exemption and this refusal are the same rule read from its two sides.

Fields

§section: String
§heading: String
§entity_type: String
§

UnterminatedFence

UNTERMINATED_FENCE: caller-supplied section content ends inside a fenced code block that never closes (consistency-sweep 04/02, criterion 1). Nothing about the parse is wrong: an open fence’s range runs to end of text in CommonMark, so every ## line the generator writes after this section lands inside the fence, is masked, and is absorbed into this section’s body on the next read. The sections then render as empty and the entity reads as healthy.

The sibling guard ValidationError::SectionContentInvalid refuses content that would BECOME a delimiter; this one refuses content that would HIDE one. Both are about the same seam from opposite sides, and neither can see the other’s case: a fence opener is not a heading line, and the heading guard’s own mask is what renders the hidden heading invisible to it.

The oracle is markdown::closing_fence_if_unterminated, the referee’s existing sentinel probe. No second fence model is written here.

Fields

§section: String
§fence: String
§

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

§section: String
§control_char: char

The offending control character (a char, since the body is already valid UTF-8 — a NUL is U+0000).

§codepoint: u32

Its Unicode scalar value, surfaced as a number for unambiguous machine reading (the string form JSON-escapes).

§byte_offset: usize

Byte offset into the section body — matches the od -c view a caller uses to locate the byte.

§

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).

Fields

§field: String
§value: String
§expected_type: String
§expected_format: Option<String>
§field_description: Option<String>
§entity_type: String

Implementations§

Source§

impl ValidationError

Source

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.

Source

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.

Source

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

Source§

fn clone(&self) -> ValidationError

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ValidationError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for ValidationError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for ValidationError

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ValidationError> for EngineError

Source§

fn from(source: ValidationError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts 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>

Converts 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)

Converts &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)

Converts &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
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Sync + Send>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Fruit for T
where T: Send + Downcast,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more