loco-rs/loco · error
Type mismatch in RefGuard
Error message
Type mismatch in RefGuard
What it means
A defensive `expect` panic in Loco's shared-store `RefGuard` access. The guard is only supposed to be created for a type after looking it up by `TypeId`, so a downcast failure means the internal type-map invariant was violated — the stored value's concrete type doesn't match `T`.
Solutions
- Check that the exact type you pass when reading the shared store matches the one inserted (including wrappers like `Arc<...>`)
- Insert the value through the typed API before creating a RefGuard for it
- If it reproduces with correct usage, file a loco-rs issue — this indicates an internal invariant violation
Example fix
// before let cfg = ctx.shared_store.get::<Config>(); // after let cfg = ctx.shared_store.get::<Arc<Config>>(); // type actually stored
Defensive patterns
Strategy: type-guard
Type guard
fn try_get<T: Any + Send + Sync>(store: &SharedStore) -> Option<RefGuard<T>> {
store.try_get::<T>()
} Prevention
- Read and write the shared store with the exact same type, including wrappers like Arc<T>
- Prefer the typed accessor APIs over raw TypeId lookups
- Document the types stored in shared_store for the whole app
When it happens
Trigger: Accessing `ctx.shared_store` with a type parameter `T` that was never stored under that `TypeId`, or a bug in the RefGuard construction path storing a mismatched concrete type.
Common situations: Requesting a shared-store value with a slightly different type than inserted (e.g. `Arc<Config>` vs `Config`); framework-level bugs after refactors of the shared_store container.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- implement `up()` for the
- only enum supported
- failed to install Ctrl+C handler
- failed to install signal handler
- logger initialization failed
AI-assisted analysis of loco-rs/loco@23639d1e36 (2026-09-12).
Data as JSON: /api/errors/45988f544fd88b3e.
Report an issue: GitHub.
Appendix: source
Thrown at src/app.rs:243
// A wrapper around DashMap's Ref type that erases the exact type
// but provides deref to the target type
pub struct RefGuard<'a, T: 'static + Send + Sync> {
inner: dashmap::mapref::one::Ref<'a, TypeId, Box<dyn Any + Send + Sync>>,
_phantom: std::marker::PhantomData<&'a T>,
}
impl<T: 'static + Send + Sync> std::ops::Deref for RefGuard<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
// This is safe because we only create a RefGuard for a specific type
// after looking it up by its TypeId
#[allow(clippy::coerce_container_to_any)]
self.inner
.value()
.downcast_ref::<T>()
.expect("Type mismatch in RefGuard")
}
}
/// Represents the application context for a web server.
///
/// This struct encapsulates various components and configurations required by
/// the web server to operate. It is typically used to store and manage shared
/// resources and settings that are accessible throughout the application's
/// lifetime.
#[derive(Clone, FromRef)]
#[allow(clippy::module_name_repetitions)]
#[non_exhaustive]
pub struct AppContext {
/// The environment in which the application is running.
pub environment: Environment,
#[cfg(feature = "with-db")]
/// A database connection used by the application.
pub db: DatabaseConnection,View on GitHub (pinned to 23639d1e36)