leptos-rs/leptos · error
could not find key for index {index:?} at {caller}
Error message
could not find key for index {index:?} at {caller} What it means
reactive_stores keys each store field's list indices with per-index keys so fine-grained reactivity can track items across moves. get_trigger_unkeyed walks a field path and, when a parent is keyed, expects a key registered for every index segment; if the key map has no entry for (path, index) it panics. This means the store's internal key bookkeeping is out of sync with the path being resolved.
Source
Thrown at reactive_stores/src/store_field.rs:153
let trigger = triggers.write().or_poisoned().get_or_insert(path);
trigger
}
#[track_caller]
fn get_trigger_unkeyed(&self, path: StorePath) -> StoreFieldTrigger {
let caller = std::panic::Location::caller();
let orig_path = path.clone();
let mut path = StorePath::with_capacity(orig_path.len());
for segment in &orig_path {
let parent_is_keyed = self.keys.contains_key(&path);
if parent_is_keyed {
let key = self
.keys
.get_key_for_index(&(path.clone(), segment.0))
.unwrap_or_else(|| {
panic!(
"could not find key for index {:?} at {}",
(path.clone(), segment.0),
caller
)
});
path.push(key);
} else {
path.push(*segment);
}
}
self.get_trigger(path)
}
#[track_caller]
fn path(&self) -> impl IntoIterator<Item = StorePathSegment> {
iter::empty()
}
View on GitHub (pinned to 32d20f6c9d)
Solutions
- Access keyed list fields consistently — do not mix keyed (.keys()/.at()) and unkeyed (.with_unkeyed()) resolution on the same path.
- Ensure reads happen while the store is in a consistent state; avoid reading store fields during mutation from another thread/task.
- Recreate or re-sync the store/field if you constructed ArcField paths manually; let the store derive keys itself.
- Upgrade leptos/reactive_stores — this is internal bookkeeping, so a fixed version may resolve the desync.
Defensive patterns
Strategy: validation
Validate before calling
// check index is within the keyed list before resolving an unkeyed path
if index < store.len() && store.keys_contains_index(path, index) { /* resolve */ } Try / catch
std::panic::catch_unwind(|| field.get_trigger_unkeyed(path, segment, caller)).err().map(|_| default_trigger)
Prevention
- Do not mix keyed and unkeyed access to the same store field path.
- Keep reactive_stores updated to the latest patch version.
- Avoid reading store triggers concurrently with structural mutations.
When it happens
Trigger: Resolving an ArcField/field path into an unkeyed store whose parent field is keyed, when the index was never registered — e.g. mixing keyed and unkeyed access to the same store field, or accessing a list index before the store registered its keys (concurrent access during resize/clear).
Common situations: Using .at(index) or keyed list fields on a store while also accessing the same path unkeyed; rapid mutation (splice/clear) racing with a render pass reading triggers for old indices; custom store field code (ArcField) built against paths the store never keyed.
Related errors
- {location:?} expected context of type {type_name:?} to be pr
- Tried to access a reactive value that has already been dispo
- <FlatRoutes> should not be used with nested routes.
- At {caller}, you call `to_server_error()` or use `server_fn_
- internal error: entered unreachable code
AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01).
Data as JSON: /api/errors/6cf1fddb26e6fc46.
Report an issue: GitHub.