{"id":"d2ccbefe110661f1","repo":"pytest-dev/pytest","slug":"session-or-parent-must-be-provided","errorCode":null,"errorMessage":"session or parent must be provided","messagePattern":"session or parent must be provided","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/nodes.py","lineNumber":176,"sourceCode":"        self.name: str = name\n\n        #: The parent collector node.\n        self.parent = parent\n\n        if config:\n            #: The pytest config object.\n            self.config: Config = config\n        else:\n            if not parent:\n                raise TypeError(\"config or parent must be provided\")\n            self.config = parent.config\n\n        if session:\n            #: The pytest session this node is part of.\n            self.session: Session = session\n        else:\n            if not parent:\n                raise TypeError(\"session or parent must be provided\")\n            self.session = parent.session\n\n        if path is None:\n            assert parent is not None\n            path = parent.path\n        #: Filesystem path where this node was collected from.\n        self.path: pathlib.Path = path\n\n        # The explicit annotation is to avoid publicly exposing NodeKeywords.\n        #: Keywords/markers collected from all scopes.\n        self.keywords: MutableMapping[str, Any] = NodeKeywords(self)\n\n        #: The marker objects belonging to this node.\n        self.own_markers: list[Mark] = []\n\n        #: Allow adding of extra keywords to use for matching.\n        self.extra_keyword_matches: set[str] = set()\n","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/nodes.py#L158-L194","documentation":"Node.__init__ requires either a parent node (session inherited from parent.session) or an explicit session object. Without one, hook routing and node identity break, so pytest raises TypeError. Relevant to plugin authors building custom nodes.","triggerScenarios":"Constructing a Node subclass with neither parent nor session, e.g. MyNode('name', config=cfg) but no session and no parent.","commonSituations":"Plugin code that supplies config but forgets session when there is no parent; partial refactor of a constructor.","solutions":["Pass a parent node so session is inherited: MyNode(name, parent=parent_node)","Otherwise pass session explicitly (and config and nodeid too)"],"exampleFix":"// before\nnode = MyNode('x', config=cfg)\n// after\nnode = MyNode('x', parent=parent_node)","handlingStrategy":"validation","validationCode":"def make_node(cls, name, *, parent=None, session=None, **kw):\n    if parent is None and session is None:\n        raise TypeError(\"provide parent or session\")\n    return cls(name, parent=parent, session=session, **kw)","typeGuard":"def has_parent_or_session(parent, session) -> bool:\n    return parent is not None or session is not None","tryCatchPattern":null,"preventionTips":["Use from_parent so session is inherited automatically","When constructing root nodes, pass session explicitly"],"tags":["nodes","plugin-api","pytest","constructor"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}