{"record":{"id":"ea0d0d126fd3474f","repo":"odysseus-dev/odysseus","slug":"imap-folder-not-found-folder","errorCode":null,"errorMessage":"IMAP folder not found: {folder}","messagePattern":"IMAP folder not found: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mcp_servers/email_server.py","lineNumber":984,"sourceCode":"# ── Tool implementations ──\n\n\ndef _list_emails(folder=\"INBOX\", max_results=20, unresponded_only=False,\n                 unread_only=False, account=None):\n    \"\"\"List emails newest-first. By default returns the latest messages,\n    including read mail, so it matches normal inbox UI expectations.\n    Pass unread_only=True and/or unresponded_only=True for attention scans.\n    account selects mailbox (None = default).\n    \"\"\"\n    fixture = _fixture_list_emails(folder, max_results, unresponded_only, unread_only, account)\n    if fixture is not None:\n        return fixture\n    conn = None\n    try:\n        conn = _imap_connect(account)\n        select_status, _ = conn.select(_q(folder), readonly=True)\n        if select_status != \"OK\":\n            raise ValueError(f\"IMAP folder not found: {folder}\")\n\n        if unread_only and unresponded_only:\n            status, data = conn.uid(\"SEARCH\", None, \"(UNSEEN UNANSWERED)\")\n        elif unread_only:\n            status, data = conn.uid(\"SEARCH\", None, \"(UNSEEN)\")\n        elif unresponded_only:\n            # Was missing — unresponded_only=True (without unread_only) fell through\n            # to \"ALL\" and returned answered mail too, despite the documented\n            # \"emails without replies\" behaviour.\n            status, data = conn.uid(\"SEARCH\", None, \"(UNANSWERED)\")\n        else:\n            # Include read too — IMAP search \"ALL\" returns the entire folder\n            status, data = conn.uid(\"SEARCH\", None, \"ALL\")\n\n        if status != \"OK\" or not data[0]:\n            return []\n\n        uid_list = list(reversed(data[0].split()))[:max_results]","sourceCodeStart":966,"sourceCodeEnd":1002,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/mcp_servers/email_server.py#L966-L1002","documentation":"Raised when conn.select(folder, readonly=True) returns a status other than 'OK', meaning the IMAP server refused the folder name. Python's imaplib does not throw for a missing mailbox; it returns 'NO', so this ValueError converts that into an explicit error naming the folder.","triggerScenarios":"Calling list_emails with folder='Inbox' against a case-sensitive server that only has 'INBOX'; requesting an archived/nested folder like 'Archive/2024' that does not exist on the server; quoting issues in the folder name passed through _q().","commonSituations":"Folder naming differences between mail providers (Gmail '[Gmail]/Sent Mail' vs plain 'Sent'); hard-coded folder names ported from another provider; folders the IMAP account cannot see due to ACLs.","solutions":["List the server's actual folders first (imaplib list() or the MCP server's folder-list tool) and use the exact returned name","Use 'INBOX', which exists on every IMAP server","Match folder-name case and any delimiters (e.g. '[Gmail]/...') exactly"],"exampleFix":"# before\nconn.select('Inbox', readonly=True)  # NO on case-sensitive servers\n# after\nstatus, folders = conn.list()\nconn.select('INBOX', readonly=True)","handlingStrategy":"validation","validationCode":"typ, data = conn.list()\nnames = [d.decode().rsplit('\"',2)[-2] for d in data]\nfolder = folder if folder in names else 'INBOX'","typeGuard":"def folder_exists(conn, folder: str) -> bool:\n    typ, data = conn.list()\n    return any(folder.encode() in (d or b'') for d in data)","tryCatchPattern":"try:\n    conn.select(_q(folder), readonly=True)\nexcept ValueError:\n    folder = 'INBOX'\n    conn.select('INBOX', readonly=True)","preventionTips":["Cache the folder list per account and refresh on this error","Use exact provider folder strings (Gmail needs '[Gmail]/Sent Mail')","Default to 'INBOX' when unsure"],"tags":["email","imap","validation"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}