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

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