{"record":{"id":"d8bf9ed4bf7a3272","repo":"Textualize/textual","slug":"query-value-is-the-wrong-type-expected-type-expe","errorCode":null,"errorMessage":"Query value is the wrong type; expected type {expect_type.__name__!r}, found {first}","messagePattern":"Query value is the wrong type; expected type (.+?), found (.+?)","errorType":"validation","errorClass":"WrongType","httpStatus":null,"severity":"error","filePath":"src/textual/css/query.py","lineNumber":244,"sourceCode":"        \"\"\"Get the *first* matching node.\n\n        Args:\n            expect_type: Require matched node is of this type,\n                or None for any type.\n\n        Raises:\n            WrongType: If the wrong type was found.\n            NoMatches: If there are no matching nodes in the query.\n\n        Returns:\n            The matching Widget.\n        \"\"\"\n        _rich_traceback_omit = True\n        if self.nodes:\n            first = self.nodes[0]\n            if expect_type is not None:\n                if not isinstance(first, expect_type):\n                    raise WrongType(\n                        f\"Query value is the wrong type; expected type {expect_type.__name__!r}, found {first}\"\n                    )\n            return first\n        else:\n            raise NoMatches(f\"No nodes match {self!r} on {self.node!r}\")\n\n    if TYPE_CHECKING:\n\n        @overload\n        def only_one(self) -> QueryType: ...\n\n        @overload\n        def only_one(self, expect_type: type[ExpectType]) -> ExpectType: ...\n\n    def only_one(\n        self, expect_type: type[ExpectType] | None = None\n    ) -> QueryType | ExpectType:\n        \"\"\"Get the *only* matching node.","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/css/query.py#L226-L262","documentation":"DOMNode.query_one / DOMQuery.first checks the first matched node against the optional expect_type; a mismatch raises WrongType stating the expected class and the actual node. This is the type-safety guard for query_one[T](...) style access so callers can rely on the returned widget's interface.","triggerScenarios":"`self.query_one(\"#header\", Static)` when #header is actually a Label subclass-less mismatch like a DataTable; `query_one(\"Button\")` matching a custom widget not subclassing Button; generic query_one[Static] on an Input.","commonSituations":"DOM changes where a widget in the markup/CSS was swapped for another type; copy-pasting query_one calls between screens; expect_type omitted then added later incorrectly.","solutions":["Change expect_type to the actual widget class (or a base class it inherits from)","Change the selector to match a node of the expected type (e.g. add an id/class to the right widget)","Drop expect_type and branch on isinstance if heterogeneous matches are legitimate"],"exampleFix":"# before\nheader = self.query_one(\"#header\", Static)  # WrongType if it's a Label\n# after\nfrom textual.widgets import Label\nheader = self.query_one(\"#header\", Label)","handlingStrategy":"type-guard","validationCode":"node = screen.query(selector).first() if screen.query(selector).nodes else None\nif node is not None and isinstance(node, Static):\n    ...","typeGuard":"def is_widget_type(node, cls) -> bool:\n    return isinstance(node, cls)","tryCatchPattern":"from textual.css.query import WrongType, NoMatches\ntry:\n    w = self.query_one(sel, Static)\nexcept WrongType:\n    w = self.query_one(sel)  # inspect actual type","preventionTips":["Prefer base classes in expect_type when subclass identity isn't required"],"tags":["textual","query","type-mismatch"],"backgroundTag":"query-type-mismatch","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}