DioxusLabs/dioxus · error
The hook list is already borrowed: This error is likely…
Error message
The hook list is already borrowed: This error is likely caused by trying to use hook inside a hook which violates the rules of hooks.
What it means
Raised when a hook tries to access the scope's hook list while it is already mutably borrowed — classically caused by calling a hook (use_signal, use_state, ...) inside another hook's initializer or from within a component body that is itself borrowing the list. Violates the rules of hooks.
Solutions
- Do not call a hook from inside another hook (including inside closures passed to hooks that run synchronously); move the inner hook call to the top level of the component body, following the rules of hooks.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at packages/core/src/scope_context.rs:382 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of DioxusLabs/dioxus@24f6a829df (2026-08-23).
Data as JSON: /api/errors/c2c63f81f62c7c5e.
Report an issue: GitHub.
Appendix: source
Thrown at packages/core/src/scope_context.rs:382
/// Queue an effect to run after the next render
pub(crate) fn queue_effect(&self, f: impl FnOnce() + 'static) {
Runtime::with(|rt| rt.queue_effect(self.id, f));
}
/// Store a value in the hook list, returning the value.
pub(crate) fn use_hook<State: Clone + 'static>(
&self,
initializer: impl FnOnce() -> State,
) -> State {
let cur_hook = self.hook_index.get();
// The hook list works by keeping track of the current hook index and pushing the index forward
// while retrieving the hook value.
self.hook_index.set(cur_hook + 1);
let mut hooks = self.hooks
.try_borrow_mut()
.expect("The hook list is already borrowed: This error is likely caused by trying to use hook inside a hook which violates the rules of hooks.");
// Try and retrieve the hook value if it exists
if let Some(existing) = self.use_hook_inner::<State>(&mut hooks, cur_hook) {
return existing;
}
// Otherwise, initialize the hook value. In debug mode, we allow hook types to change after a hot patch
self.push_hook_value(&mut hooks, cur_hook, initializer())
}
// The interior version that gets monomorphized by the `State` type but not the `initializer` type.
// This helps trim down binary sizes
fn use_hook_inner<State: Clone + 'static>(
&self,
hooks: &mut Vec<Box<dyn std::any::Any>>,
cur_hook: usize,
) -> Option<State> {
hooks.get(cur_hook).and_then(|inn| {View on GitHub (pinned to 24f6a829df)