odysseus-dev/odysseus · error · ValueError
Email account not found for selector {account!r}. Available
Error message
Email account not found for selector {account!r}. Available accounts: {available} What it means
Raised when an explicit account selector is passed to an email MCP tool and the accounts DB has owner-scoped rows, but _resolve_account_from_rows() finds no match for that selector (id, name, or imap_user). The message enumerates every available account so the caller can immediately pick a valid selector.
Source
Thrown at mcp_servers/email_server.py:324
EMAIL_CACHE_DB,
),
"account_id": None,
"account_name": None,
}
raw_rows = _read_accounts_from_db()
if _mcp_owner_required(raw_rows):
raise ValueError(_OWNER_SCOPE_ERROR)
rows = _filter_accounts_for_owner(raw_rows)
row = _resolve_account_from_rows(rows, account)
if _current_owner() and raw_rows and not rows:
raise ValueError("No email account is configured for the authenticated owner")
if account and rows and not row:
available = ", ".join(
f"{r.get('name') or r.get('imap_user')} <{r.get('imap_user') or r.get('from_address') or '?'}>"
for r in rows
)
raise ValueError(f"Email account not found for selector {account!r}. Available accounts: {available}")
if row:
cfg["account_id"] = row["id"]
cfg["account_name"] = row["name"]
cfg["imap_host"] = row["imap_host"] or cfg["imap_host"]
cfg["imap_port"] = int(row["imap_port"] or cfg["imap_port"])
cfg["imap_user"] = row["imap_user"] or cfg["imap_user"]
# Passwords in email_accounts are stored encrypted via
# src.secret_storage.encrypt — decrypt before handing to IMAP
# (same path email_helpers.py:369 uses). Falling back to the raw
# ciphertext is what produced AUTHENTICATIONFAILED previously.
try:
from src.secret_storage import decrypt as _decrypt
except Exception:
_decrypt = lambda v: v # noqa: E731
cfg["imap_password"] = _decrypt(row["imap_password"]) if row["imap_password"] else cfg["imap_password"]
cfg["imap_starttls"] = bool(row["imap_starttls"])
# The email_accounts table stores STARTTLS but not an explicit IMAP SSL
# flag. Port 993 is implicit TLS for IMAP providers like Gmail.View on GitHub (pinned to f9235ebbf1)
Solutions
- Read the 'Available accounts:' list in the message and use one of those exact selectors
- If the account should exist, confirm it in the accounts DB and that its owner matches the authenticated owner
- Omit the account argument to let the server resolve the default account
Example fix
# before emails = list_emails(folder='INBOX', account='old-name') # after — use a selector from the error's Available accounts list emails = list_emails(folder='INBOX', account='main <me@example.com>')
Defensive patterns
Strategy: validation
Validate before calling
selectors = {r.get('id'), r.get('name'), r.get('imap_user')} | {None}
if account not in selectors:
account = None # fall back to default resolution Type guard
def is_valid_selector(rows: list[dict], sel: str | None) -> bool:
return sel is None or any(sel in (r.get('id'), r.get('name'), r.get('imap_user')) for r in rows) Try / catch
try:
_load_config(account)
except ValueError as e:
if 'not found for selector' in str(e):
parse_available_from(e) # message lists valid selectors
raise Prevention
- Resolve account selectors dynamically, never hard-code them
- Parse the Available accounts list from the error to self-correct
- Rename accounts only through the API so dependent scripts can be updated together
When it happens
Trigger: Passing account=<name>, <id>, or <imap_user> that does not match any row visible to the current owner — e.g. a stale account name after the account was renamed or deleted, or a typo in the selector string.
Common situations: Hard-coded account names in scripts that outlive account renames; copy-pasting selectors between environments (dev DB vs prod DB); using an account owned by a different user under multi-owner scoping.
Related errors
- Cannot create reply: sender address is missing from this ema
- Error: email MCP requires an authenticated owner or ODYSSEUS
- No email account is configured for the authenticated owner
- IMAP folder not found: {folder}
- Invalid draft payload: {exc}
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/c48030b320cdd121.
Report an issue: GitHub.