tauri-apps/tauri · error · InvokeError

state not managed for field `{}` on command `{}`. You must c

Error message

state not managed for field `{}` on command `{}`. You must call `.manage()` before using this command

What it means

Tauri commands can request managed state via a State<'_, T> parameter. CommandArg::from_command looks the value up by TypeId in the state container; if nothing of exactly that type was registered with Builder::manage/App::manage beforehand, try_get returns None and the command invocation is rejected with this error, naming the state field and the command.

Source

Thrown at crates/tauri/src/state.rs:63

}

impl<T: PartialEq> PartialEq for State<'_, T> {
  fn eq(&self, other: &Self) -> bool {
    self.0 == other.0
  }
}

impl<T: std::fmt::Debug> std::fmt::Debug for State<'_, T> {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    f.debug_tuple("State").field(&self.0).finish()
  }
}

impl<'r, 'de: 'r, T: 'static, R: Runtime> CommandArg<'de, R> for State<'r, T> {
  /// Grabs the [`State`] from the [`CommandItem`]. This will never fail.
  fn from_command(command: CommandItem<'de, R>) -> Result<Self, InvokeError> {
    command.message.state_ref().try_get().ok_or_else(|| {
      InvokeError::from_anyhow(anyhow::anyhow!(
        "state not managed for field `{}` on command `{}`. You must call `.manage()` before using this command",
        command.key, command.name
      ))
    })
  }
}

// Taken from: https://github.com/SergioBenitez/state/blob/556c1b94db8ce8427a0e72de7983ab5a9af4cc41/src/ident_hash.rs
// This is a _super_ stupid hash. It just uses its input as the hash value. This
// hash is meant to be used _only_ for "prehashed" values. In particular, we use
// this so that hashing a TypeId is essentially a noop. This is because TypeIds
// are already unique integers.
#[derive(Default)]
struct IdentHash(u64);

impl std::hash::Hasher for IdentHash {
  fn finish(&self) -> u64 {
    self.0

View on GitHub (pinned to 2f1cd75b0f)

Solutions

  1. Register the state before the app runs: tauri::Builder::default().manage(MyState::new())...invoke_handler(...).run(...)
  2. Make the managed type exactly match the command parameter, including Mutex<>/RwLock<> wrappers ('static, Send + Sync)
  3. If timing is the issue, move manage() into Builder::setup (or onto the builder before run) so it always precedes the first invoke
  4. For genuinely optional state, fetch with app.try_state::<T>() and handle None instead of failing

Example fix

// before: command needs State<AppStore> but nothing was managed
#[tauri::command]
fn items(state: State<AppStore>) -> Vec<Item> { state.all() }

// after
fn main() {
  tauri::Builder::default()
    .manage(AppStore::new())
    .invoke_handler(tauri::generate_handler![items])
    .run(tauri::generate_context!())
    .unwrap();
}
Defensive patterns

Strategy: validation

Type guard

// Rust: check state is managed before invoking command logic
fn state_ready<T: Send + Sync + 'static>(app: &tauri::AppHandle) -> bool {
  app.try_state::<T>().is_some()
}

Try / catch

// frontend: distinguish the 'not managed' rejection from other command errors
try {
  await invoke('get_items')
} catch (e) {
  if (String(e).includes('state not managed')) {
    // initialization order bug: ensure .manage() runs before first invoke; surface a setup hint
  } else throw e
}

Prevention

When it happens

Trigger: Invoking a command from the frontend (invoke('my_command')) whose signature includes a State<'_, T> parameter while the app never called .manage(...) for T; also when the managed type differs from the requested type (e.g. managed Mutex<Store> but requested State<Store>), or when the invoke races ahead of the manage() call in setup.

Common situations: Adding a State parameter to a command but forgetting .manage(); refactoring the type (wrapping in Mutex/RwLock, renaming) so TypeIds no longer match; invoking commands during window creation before setup managed the state.

Related errors


AI-assisted analysis of tauri-apps/tauri@2f1cd75b0f (2026-08-16). Data as JSON: /api/errors/07e6af003ab96506. Report an issue: GitHub.