glzr-io/glazewm · error

Cannot attach an already attached container.

Error message

Cannot attach an already attached container.

What it means

`attach_container` inserts a detached container into a new parent, but only if it is truly detached. Calling it on a container that still has a parent violates the tree invariant, so it bails before mutating anything.

Solutions

  1. Call `detach_container` on the child before attaching it
  2. Guard the call with `if child.is_detached()` and skip/log otherwise
  3. Fix the caller logic so a container is only attached once per event

Example fix

// before
attach_container(&child, &parent, Some(0))?;
// after
detach_container(&child);
attach_container(&child, &parent, Some(0))?;
Defensive patterns

Strategy: validation

Validate before calling

if !child.is_detached() {
  detach_container(&child);
}
attach_container(&child, &target_parent, target_index)?;

Try / catch

match attach_container(&child, &parent, Some(0)) {
  Err(e) if e.to_string().contains("already attached") => { /* skip or detach first */ }
  r => r?,
}

Prevention

When it happens

Trigger: Calling `attach_container(&child, &parent, Some(i))` where `child.is_detached()` is false — i.e. the container is already in the container tree.

Common situations: Command handlers that forgot to call `detach_container` first, or re-running an attach on the same container due to a duplicated window event.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of glzr-io/glazewm@5709ad0a3c (2026-09-08). Data as JSON: /api/errors/040a6ffec98931c4. Report an issue: GitHub.

Appendix: source

Thrown at packages/wm/src/commands/container/attach_container.rs:18

use anyhow::bail;

use super::resize_tiling_container;
use crate::{
  models::Container,
  traits::{CommonGetters, TilingSizeGetters},
};

/// Inserts a child container at the specified index.
///
/// The inserted child will be resized to fit the available space.
pub fn attach_container(
  child: &Container,
  target_parent: &Container,
  target_index: Option<usize>,
) -> anyhow::Result<()> {
  if !child.is_detached() {
    bail!("Cannot attach an already attached container.");
  }

  if let Some(target_index) = target_index {
    // Ensure target index is within the bounds of the parent's children.
    let target_index = target_index.clamp(0, target_parent.child_count());

    // Insert the child at the specified index.
    target_parent
      .borrow_children_mut()
      .insert(target_index, child.clone());
  } else {
    target_parent.borrow_children_mut().push_back(child.clone());
  }

  target_parent
    .borrow_child_focus_order_mut()
    .push_back(child.id());

View on GitHub (pinned to 5709ad0a3c)