{"record":{"id":"75a0c06d20f949e5","repo":"Textualize/textual","slug":"a-widget-can-t-be-its-own-parent","errorCode":null,"errorMessage":"A widget can't be its own parent","messagePattern":"A widget can't be its own parent","errorType":"exception","errorClass":"WidgetError","httpStatus":null,"severity":"error","filePath":"src/textual/widget.py","lineNumber":498,"sourceCode":"        self._styles_cache = StylesCache()\n        self._rich_style_cache: dict[tuple[str, ...], tuple[Style, Style]] = {}\n        self._visual_style_cache: dict[tuple[str, ...], VisualStyle] = {}\n\n        self._tooltip: VisualType | None = None\n        \"\"\"The tooltip content.\"\"\"\n        self.absolute_offset: Offset | None = None\n        \"\"\"Force an absolute offset for the widget (used by tooltips).\"\"\"\n\n        self._scrollbar_changes: set[tuple[bool, bool]] = set()\n        \"\"\"Used to stabilize scrollbars.\"\"\"\n        super().__init__(\n            name=name,\n            id=id,\n            classes=self.DEFAULT_CLASSES if classes is None else classes,\n        )\n\n        if self in children:\n            raise WidgetError(\"A widget can't be its own parent\")\n\n        for child in children:\n            if not isinstance(child, Widget):\n                raise TypeError(\n                    f\"Widget positional arguments must be Widget subclasses; not {child!r}\"\n                )\n        self._pending_children = list(children)\n        self.set_reactive(Widget.disabled, disabled)\n        if self.BORDER_TITLE:\n            self.border_title = self.BORDER_TITLE\n        if self.BORDER_SUBTITLE:\n            self.border_subtitle = self.BORDER_SUBTITLE\n\n        self.lock = RLock()\n        \"\"\"`asyncio` lock to be used to synchronize the state of the widget.\n\n        Two different tasks might call methods on a widget at the same time, which\n        might result in a race condition.","sourceCodeStart":480,"sourceCodeEnd":516,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/widget.py#L480-L516","documentation":"Widget constructor guard: a widget instance was passed as one of its own children, which would create a self-referential DOM cycle.","triggerScenarios":"Widget(children=[...]) where the list contains the widget being constructed, e.g. via aliasing or building containers imperatively before init completes.","commonSituations":"Dynamic child lists that accidentally include 'self' due to variable reuse or a copy-paste in list building.","solutions":["Remove the self-reference from the children list","Build the tree top-down: create children first, then the parent","Use mount() after construction for dynamic structures"],"exampleFix":"# before\nchildren = [panel]\nbox = Container(box, *children)  # oops\n# after\nbox = Container(*children)","handlingStrategy":"validation","validationCode":"assert all(child is not self for child in children)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build child lists without self-references","Use mount() for dynamic trees"],"tags":["widget","dom-tree","constructor","textual"],"backgroundTag":"self-referential-parent","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}