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
- Call `detach_container` on the child before attaching it
- Guard the call with `if child.is_detached()` and skip/log otherwise
- 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
- Always detach before attaching in command handlers
- Track container attachment state explicitly in window event handlers
- Write unit tests covering double-attach scenarios
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)