{"record":{"id":"80b6bb06fce09f3e","repo":"Textualize/textual","slug":"cannot-use-default-as-a-custom-mode","errorCode":null,"errorMessage":"Cannot use '_default' as a custom mode.","messagePattern":"Cannot use '_default' as a custom mode\\.","errorType":"validation","errorClass":"InvalidModeError","httpStatus":null,"severity":"error","filePath":"src/textual/app.py","lineNumber":2688,"sourceCode":"        self.screen.post_message(events.ScreenResume())\n\n        self.log.system(f\"{self._current_mode!r} is the current mode\")\n        self.log.system(f\"{self.screen} is active\")\n\n        return await_mount\n\n    def add_mode(self, mode: str, base_screen: str | Callable[[], Screen]) -> None:\n        \"\"\"Adds a mode and its corresponding base screen to the app.\n\n        Args:\n            mode: The new mode.\n            base_screen: The base screen associated with the given mode.\n\n        Raises:\n            InvalidModeError: If the name of the mode is not valid/duplicated.\n        \"\"\"\n        if mode == \"_default\":\n            raise InvalidModeError(\"Cannot use '_default' as a custom mode.\")\n        elif mode in self._modes:\n            raise InvalidModeError(f\"Duplicated mode name {mode!r}.\")\n\n        if isinstance(base_screen, Screen):\n            raise TypeError(\n                \"add_mode() must be called with a Screen type, not an instance\"\n                f\" (got instance of {type(base_screen).__name__})\"\n            )\n        self._modes[mode] = base_screen\n\n    def remove_mode(self, mode: str) -> AwaitComplete:\n        \"\"\"Removes a mode from the app.\n\n        Screens that are running in the stack of that mode are scheduled for pruning.\n\n        Args:\n            mode: The mode to remove. It can't be the active mode.\n","sourceCodeStart":2670,"sourceCodeEnd":2706,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/app.py#L2670-L2706","documentation":"InvalidModeError raised by App.add_mode when the mode name is the reserved string \"_default\". Textual uses \"_default\" internally for the initial screen stack and it cannot be overridden.","triggerScenarios":"await app.add_mode(\"_default\", MyScreen) or MODES containing a \"_default\" key.","commonSituations":"Generic code that programmatically registers modes from a list that includes a default entry.","solutions":["Choose any other mode name, e.g. \"main\" or \"home\"","Filter/alias the reserved name when generating modes dynamically"],"exampleFix":"# before\nawait app.add_mode(\"_default\", HomeScreen)\n\n# after\nawait app.add_mode(\"home\", HomeScreen)","handlingStrategy":"validation","validationCode":"assert mode != '_default', \"'_default' is reserved\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat '_default' as reserved","Filter generated mode lists for reserved names"],"tags":["modes","reserved-name","textual"],"backgroundTag":"reserved-name-conflict","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}