{"record":{"id":"c014270321231533","repo":"Textualize/textual","slug":"duplicated-mode-name-mode-r","errorCode":null,"errorMessage":"Duplicated mode name {mode!r}.","messagePattern":"Duplicated mode name (.+?)\\.","errorType":"validation","errorClass":"InvalidModeError","httpStatus":null,"severity":"error","filePath":"src/textual/app.py","lineNumber":2690,"sourceCode":"        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\n        Raises:\n            ActiveModeError: If trying to remove the active mode.","sourceCodeStart":2672,"sourceCodeEnd":2708,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/app.py#L2672-L2708","documentation":"InvalidModeError raised by App.add_mode when the mode name already exists in self._modes. Mode names must be unique; add_mode never overwrites.","triggerScenarios":"Calling add_mode(\"editor\", ...) twice, or add_mode with a name already declared in the MODES class variable.","commonSituations":"Repeated init/on_mount calls registering modes; merging runtime modes with class-declared ones without checking existence.","solutions":["Check membership first: if \"editor\" not in app._modes: await app.add_mode(...)","Use remove_mode before re-adding a mode you want to replace","Consolidate: declare all static modes in MODES and only add_mode for dynamic ones"],"exampleFix":"# before\nawait app.add_mode(\"editor\", EditorScreen)  # second call crashes\n\n# after\nif \"editor\" not in self._modes:\n    await self.add_mode(\"editor\", EditorScreen)","handlingStrategy":"validation","validationCode":"if mode not in app._modes:\n    await app.add_mode(mode, screen_cls)","typeGuard":null,"tryCatchPattern":"try:\n    await app.add_mode(mode, screen_cls)\nexcept InvalidModeError:\n    await app.remove_mode(mode)\n    await app.add_mode(mode, screen_cls)","preventionTips":["Membership-check before add_mode","remove_mode first when intentionally replacing"],"tags":["modes","duplicate-key","textual"],"backgroundTag":"duplicate-registration","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}