GraphiteEditor/Graphite · error
Parent accessed via child should have children
Error message
Parent accessed via child should have children
What it means
can_be_clipped checks that a layer is NOT the last child of its stack (used to decide clipping). It does parent(metadata).is_some_and(|layer| layer.last_child(metadata).expect(...)). The expect encodes a DocumentMetadata invariant: if a node has a parent link, that parent must have child links (first_child/last_child). The panic fires when that invariant breaks - the parent's relations exist and point to a parent, but that parent's last_child is None, i.e. corrupted/half-updated layer tree metadata.
Source
Thrown at editor/src/messages/portfolio/document/utility_types/document_metadata.rs:362
/// Does the layer have children? If so, then it is a folder.
pub fn has_children(self, metadata: &DocumentMetadata) -> bool {
self.first_child(metadata).is_some()
}
/// Is the layer a child of the given layer?
pub fn is_child_of(self, metadata: &DocumentMetadata, parent: &LayerNodeIdentifier) -> bool {
parent.children(metadata).any(|child| child == self)
}
/// Is the layer an ancestor of the given layer?
pub fn is_ancestor_of(self, metadata: &DocumentMetadata, child: &LayerNodeIdentifier) -> bool {
child.ancestors(metadata).any(|ancestor| ancestor == self)
}
/// Is the layer the last child of its stack? Used for clipping
pub fn can_be_clipped(self, metadata: &DocumentMetadata) -> bool {
self.parent(metadata)
.is_some_and(|layer| layer.last_child(metadata).expect("Parent accessed via child should have children") != self)
}
/// Iterator over all direct children (excluding self and recursive children)
pub fn children(self, metadata: &DocumentMetadata) -> AxisIter<'_> {
AxisIter {
layer_node: self.first_child(metadata),
next_node: Self::next_sibling,
metadata,
}
}
pub fn downstream_siblings(self, metadata: &DocumentMetadata) -> AxisIter<'_> {
AxisIter {
layer_node: Some(self),
next_node: Self::previous_sibling,
metadata,
}
}View on GitHub (pinned to c507b35645)
Solutions
- Make the check total: layer.last_child(metadata) != Some(self) so a missing child link simply reports 'cannot clip' instead of panicking
- Find the mutation path that broke the invariant (log parent/children state when it triggers) and fix its metadata bookkeeping
- Add a debug-mode metadata consistency validator that walks parent<->child links after every structural message
Example fix
// before
self.parent(metadata).is_some_and(|layer| layer.last_child(metadata).expect("Parent accessed via child should have children") != self)
// after
self.parent(metadata).is_some_and(|layer| layer.last_child(metadata) != Some(self)) Defensive patterns
Strategy: validation
Validate before calling
// total version of the check: missing child links simply mean 'cannot clip'
let clip_allowed = match self.parent(metadata) {
Some(parent) => parent.last_child(metadata) != Some(self),
None => false,
}; Type guard
fn parent_has_children(layer: LayerNodeIdentifier, metadata: &DocumentMetadata) -> bool {
layer.first_child(metadata).is_some()
} Prevention
- Never .expect inside tree walks; model missing links as 'condition false'
- Maintain parent and child pointers together in every structural mutation (single helper that writes both)
- Run a metadata consistency check (parent<->children bidirectionality) in debug builds after each graph message
When it happens
Trigger: Any structural graph edit (delete, move, reorder, undo/redo of layer operations) that writes parent pointers without maintaining the corresponding first_child/last_child links, or deserialized older documents whose metadata was not fully rebuilt.
Common situations: Undo of a layer deletion leaving a dangling parent relation; custom code calling NodeGraphMessage handlers out of order; bugs in metadata recomputation after loading migrated documents.
Related errors
- Ungrouped folder must have a parent
- In `check_layer()`: there should be a `target`
- Path should not be empty
- Handle cannot be converted
- If `selection_shape` is a polygon then subpath is constructe
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/7e61a134700d05f3.
Report an issue: GitHub.