{"record":{"id":"040a6ffec98931c4","repo":"glzr-io/glazewm","slug":"cannot-attach-an-already-attached-container","errorCode":null,"errorMessage":"Cannot attach an already attached container.","messagePattern":"Cannot attach an already attached container\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/wm/src/commands/container/attach_container.rs","lineNumber":18,"sourceCode":"use anyhow::bail;\r\n\r\nuse super::resize_tiling_container;\r\nuse crate::{\r\n  models::Container,\r\n  traits::{CommonGetters, TilingSizeGetters},\r\n};\r\n\r\n/// Inserts a child container at the specified index.\r\n///\r\n/// The inserted child will be resized to fit the available space.\r\npub fn attach_container(\r\n  child: &Container,\r\n  target_parent: &Container,\r\n  target_index: Option<usize>,\r\n) -> anyhow::Result<()> {\r\n  if !child.is_detached() {\r\n    bail!(\"Cannot attach an already attached container.\");\r\n  }\r\n\r\n  if let Some(target_index) = target_index {\r\n    // Ensure target index is within the bounds of the parent's children.\r\n    let target_index = target_index.clamp(0, target_parent.child_count());\r\n\r\n    // Insert the child at the specified index.\r\n    target_parent\r\n      .borrow_children_mut()\r\n      .insert(target_index, child.clone());\r\n  } else {\r\n    target_parent.borrow_children_mut().push_back(child.clone());\r\n  }\r\n\r\n  target_parent\r\n    .borrow_child_focus_order_mut()\r\n    .push_back(child.id());\r\n\r","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/glzr-io/glazewm/blob/5709ad0a3c7c386bbc3e38166a865ffc12937515/packages/wm/src/commands/container/attach_container.rs#L1-L36","documentation":"`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.","triggerScenarios":"Calling `attach_container(&child, &parent, Some(i))` where `child.is_detached()` is false — i.e. the container is already in the container tree.","commonSituations":"Command handlers that forgot to call `detach_container` first, or re-running an attach on the same container due to a duplicated window event.","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"],"exampleFix":"// before\nattach_container(&child, &parent, Some(0))?;\n// after\ndetach_container(&child);\nattach_container(&child, &parent, Some(0))?;","handlingStrategy":"validation","validationCode":"if !child.is_detached() {\n  detach_container(&child);\n}\nattach_container(&child, &target_parent, target_index)?;","typeGuard":null,"tryCatchPattern":"match attach_container(&child, &parent, Some(0)) {\n  Err(e) if e.to_string().contains(\"already attached\") => { /* skip or detach first */ }\n  r => r?,\n}","preventionTips":["Always detach before attaching in command handlers","Track container attachment state explicitly in window event handlers","Write unit tests covering double-attach scenarios"],"tags":["state","container-tree","invariant"],"backgroundTag":"invalid-state-transition","analyzedSha":"5709ad0a3c7c386bbc3e38166a865ffc12937515","analyzedAt":"2026-09-08T03:26:40.288Z","contentChangedAt":"2026-09-08T03:26:40.288Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}