> ## Documentation Index
> Fetch the complete documentation index at: https://rydantic.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Per-call business context

> Explicit request data for owned model validation

> [!NOTE]
>
> These APIs require **0.8.0-beta.1** and are not included in stable 0.7.0.
> They are available in the opt-in prerelease. Install with
> `rydantic = "=0.8.0-beta.1"`.
> See [release status](/reference/releases) and the breaking panic-boundary contract
> below. The default installation remains stable 0.7.0.

Owned `Model` entry points accept explicit business data through their
`_with_context` variants. For example:

```rust theme={"system"}
use rydantic::{Context, Model, ValidationError};
use std::sync::Arc;

struct Policy { maximum: u32 }
fn allowed(value: &u32, ctx: &Context) -> Result<(), ValidationError> {
    let policy = ctx.require_data::<Policy>()?;
    if *value > policy.maximum {
        Err(ValidationError::new("limit", "request limit exceeded"))
    } else {
        Ok(())
    }
}
#[derive(Model)]
struct Request {
    #[model(validate_with_context = allowed)]
    amount: u32,
}
let policy = Arc::new(Policy { maximum: 10 });
let request = Request::parse_json_with_context(r#"{"amount":8}"#, policy.clone())?;
request.validate_with_context(policy.clone())?;
let json = request.dump_json_with_context(policy)?;
# Ok::<(), rydantic::ValidationErrors>(())
```

The same `Arc` is carried through nested containers, child collectors, synchronous
validation, async validation, and encoding. Context-aware callback forms receive
an immutable `&Context`; use `require_data::<Policy>()?` to require the exact type.
Missing data returns `context_missing`; a different supplied type returns
`context_type_mismatch`. These are ordinary validation errors at the callback's
location, not panics or default values. Retrieval is checked at runtime; it does
not make the derive's business-context type statically enforced.

Synchronous methods are `parse_json_with_context`, `parse_slice_with_context`,
`parse_reader_with_context`, `parse_raw_with_context`, `parse_value_with_context`,
`validate_with_context`, `dump_with_context`, and `dump_json_with_context`.
Async methods append `_with_context` to existing async names, e.g.
`parse_json_async_with_context` and `validate_async_with_context`; raw/value parse
and dump/dump\_json also have these variants. Synchronous methods still reject
models requiring async checks. Async checks only run after synchronous success.

## Ownership and isolation

Business data must implement `Any + Send + Sync`, which requires `'static` owned
data. It cannot contain non-static borrowed request references or `Rc`/`RefCell`
state. An owned struct with strings or `Arc` handles works. Context itself does
not clone business data, mutate it, or store it globally. Debug output omits the
payload. Each invocation has a fresh error/path collector. Distinct request data
is isolated; deliberately reusing the same `Arc` or putting shared mutable state
inside it is the caller's responsibility, not an isolation guarantee provided by
the library. Cancellation drops the owned context references with the future.

Untagged-enum branch trials share the same `Arc` payload. Their collectors isolate
diagnostic paths and errors, not application state or side effects. Mutations or
external effects from a failed alternative persist; there is no rollback.

The resulting model does not retain context. Supply the data again when
revalidating or dumping. Ordinary entry points, serde, `Validated`, and
`AsyncValidated` remain context-free; context-required callbacks return a missing
context error when invoked there. They do not silently skip required checks.
Existing high-level Axum, SQL and Cap’n Proto integration paths also create their
own context-free collectors: they do not automatically forward business data or
support context-required callbacks. Use the explicit owned `Model` context entry
points or deliberately wire context through an appropriate low-level integration.
`BorrowModel` high-level context entry points are not provided in this initial
API. Low-level custom decoders/checkers may use `Context::with_data` and
`Context::require_data`, propagate children with `Context::child`, and push
relative errors into the active collector once. Do not include business secrets
in custom error messages or parameters if those errors will be exposed publicly.

## Panic-boundary compatibility

**Breaking from 0.7.0:** `Context` no longer implements the automatic
`UnwindSafe` and `RefUnwindSafe` marker traits, even when created without data.
Its erased `Arc<dyn Any + Send + Sync>` payload does not retain those markers,
even if the concrete application data would have satisfied them. Code that
captures a context across `std::panic::catch_unwind`, or requires those bounds,
may therefore stop compiling.

Prefer constructing and consuming the collector inside the closure, or avoid
capturing it across the panic boundary. Other captured state must still meet the
closure's requirements. Use `AssertUnwindSafe` only when the application has
explicitly audited every captured value and any shared payload for panic safety;
never blindly wrap the context or whole closure just to silence the error.
Validation errors remain ordinary `Result` values and do not require catching
panics. No compatibility layer restores the old auto-trait contract.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.