{"record":{"id":"e5daef969b35fb25","repo":"langchain-ai/deepagents","slug":"mcp-login-was-cancelled-before-the-prompt-could-be","errorCode":null,"errorMessage":"MCP login was cancelled before the prompt could be shown.","messagePattern":"MCP login was cancelled before the prompt could be shown\\.","errorType":"exception","errorClass":"MCPLoginCancelledError","httpStatus":null,"severity":"info","filePath":"libs/code/deepagents_code/tui/widgets/mcp_login.py","lineNumber":428,"sourceCode":"        self._history_widget.mount(\n            Static(line, classes=\"ml-history-line\", markup=False)\n        )\n        self._history_widget.scroll_end(animate=False)\n\n    async def _await_input(self, prompt: str) -> str:\n        \"\"\"Show `prompt`, wait for `Enter`, and return the typed value.\n\n        Returns:\n            The raw input value the user submitted.\n\n        Raises:\n            MCPLoginCancelledError: When the modal is cancelled before or\n                during submission.\n            RuntimeError: When a concurrent prompt is already active.\n        \"\"\"\n        if self._cancelled:\n            msg = \"MCP login was cancelled before the prompt could be shown.\"\n            raise MCPLoginCancelledError(msg)\n        if self._pending_input is not None:\n            msg = (\n                \"MCP login modal cannot have two concurrent input prompts; \"\n                \"the previous prompt was not resolved.\"\n            )\n            raise RuntimeError(msg)\n\n        loop = asyncio.get_running_loop()\n        future: asyncio.Future[str] = loop.create_future()\n        self._pending_input = future\n        if self._prompt_widget is not None:\n            self._prompt_widget.display = True\n            self._prompt_widget.update(prompt)\n        if self._input_widget is not None:\n            self._input_widget.value = \"\"\n            self._input_widget.display = True\n            self._input_widget.focus()\n        try:","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/tui/widgets/mcp_login.py#L410-L446","documentation":"_await_input shows the MCP login modal's input prompt. If the modal was already cancelled before the prompt could be presented, it raises MCPLoginCancelledError with this message rather than waiting on an input that will never arrive. A separate RuntimeError guards against two concurrent prompts.","triggerScenarios":"Calling request_callback_url (which awaits _await_input) after the user has already dismissed/cancelled the MCP login modal — self._cancelled is True at entry.","commonSituations":"User presses Esc/closes the modal while a login step is being prepared; an auth flow that retries a prompt after cancellation; a timeout path cancelling the modal then code continuing to request input.","solutions":["Check the modal's cancelled state before requesting the callback URL and abort the login flow early.","Catch MCPLoginCancelledError around request_callback_url and treat it as a normal user cancellation (no error UI).","Ensure a single login flow owns the modal so cancel and prompt paths don't race."],"exampleFix":"// before\nurl = await modal.request_callback_url()  # raises if cancelled\n// after\ntry:\n    url = await modal.request_callback_url()\nexcept MCPLoginCancelledError:\n    return  # user cancelled login","handlingStrategy":"try-catch","validationCode":"if modal.is_cancelled:\n    return  # skip request_callback_url entirely\nurl = await modal.request_callback_url()","typeGuard":null,"tryCatchPattern":"try:\n    url = await modal.request_callback_url()\nexcept MCPLoginCancelledError:\n    return  # user cancelled; exit login flow quietly","preventionTips":["Check the modal's cancelled flag before each login step.","Ensure only one owner drives the login modal at a time.","Treat MCPLoginCancelledError as a normal exit path, not an error to report."],"tags":["mcp","auth","ui-cancel"],"backgroundTag":"user-cancelled-flow","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}