{"record":{"id":"8099004b37122289","repo":"Textualize/textual","slug":"modes-cannot-contain-instances-use-a-type-instead","errorCode":null,"errorMessage":"MODES cannot contain instances, use a type instead (got instance of {type(_screen).__name__} for {mode!r})","messagePattern":"MODES cannot contain instances, use a type instead \\(got instance of (.+?) for (.+?)\\)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/textual/app.py","lineNumber":2605,"sourceCode":"        Args:\n            mode: Name of the mode.\n\n        Returns:\n            An optionally awaitable object which can be awaited until the screen\n            associated with the mode has been mounted.\n        \"\"\"\n\n        stack = self._screen_stacks.get(mode, [])\n        if stack:\n            # Mode already exists\n            # Return an dummy await\n            return AwaitMount(stack[0], [])\n\n        if mode in self._modes:\n            # Mode is defined in MODES\n            _screen = self._modes[mode]\n            if isinstance(_screen, Screen):\n                raise TypeError(\n                    \"MODES cannot contain instances, use a type instead \"\n                    f\"(got instance of {type(_screen).__name__} for {mode!r})\"\n                )\n            new_screen: Screen | str = _screen() if callable(_screen) else _screen\n            screen, await_mount = self._get_screen(new_screen)\n            stack.append(screen)\n            self._load_screen_css(screen)\n            if screen._css_update_count != self._css_update_count:\n                self.refresh_css()\n\n            screen.post_message(events.ScreenResume())\n        else:\n            # Mode is not defined\n            screen = self.get_default_screen()\n            stack.append(screen)\n            self._register(self, screen)\n            screen.post_message(events.ScreenResume())\n            await_mount = AwaitMount(stack[0], [])","sourceCodeStart":2587,"sourceCodeEnd":2623,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/app.py#L2587-L2623","documentation":"TypeError raised in App mode-switching code when a MODES entry is an instantiated Screen. At switch time Textual calls the entry (factory) to build the screen; an instance cannot be safely reused across mode activations.","triggerScenarios":"MODES = {\"editor\": EditorScreen(app)} and then switch_mode(\"editor\").","commonSituations":"Trying to pass state into a mode by pre-instantiating the screen; works once in prototypes but violates the API contract.","solutions":["Store the class or a callable: MODES = {\"editor\": EditorScreen}","Pass state via screen constructor through a lambda/partial factory: MODES = {\"editor\": lambda: EditorScreen(item)}","Alternatively use add_mode with a callable"],"exampleFix":"# before\nclass MyApp(App):\n    MODES = {\"editor\": EditorScreen()}\n\n# after\nclass MyApp(App):\n    MODES = {\"editor\": EditorScreen}","handlingStrategy":"type-guard","validationCode":"assert not isinstance(MODES['editor'], Screen), 'MODES needs the class/factory'","typeGuard":"def is_mode_factory(v) -> bool:\n    return isinstance(v, str) or (callable(v) and not isinstance(v, Screen))","tryCatchPattern":null,"preventionTips":["Pass Screen classes in MODES","Use lambda factories for constructor args"],"tags":["modes","screens","typeerror","textual"],"backgroundTag":"instance-instead-of-class","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}