Skip to content

fix(agents): handle unresolvable task_data IDs - #595

Open
rohanbuilds-ai wants to merge 1 commit into
GenAI-Security-Project:mainfrom
rohanbuilds-ai:fix/agent-unresolvable-task-data-error-handling
Open

rohanbuilds-ai wants to merge 1 commit into
GenAI-Security-Project:mainfrom
rohanbuilds-ai:fix/agent-unresolvable-task-data-error-handling

Conversation

@rohanbuilds-ai

Copy link
Copy Markdown

Summary

  • Gracefully handle missing, invalid, or unresolvable vendor_id and invoice_id in specialized agent prompt construction (VendorOnboardingAgent, InvoiceAgent).
  • Protect BaseAgent setup steps (_connect_mcp_servers, _get_user_prompt, workflow context registration) so unexpected failures return a structured task_status="failed" result instead of raising unhandled exceptions out of process().
  • Ensure MCP servers are disconnected and workflow context is cleared in finally even if setup fails or if disconnecting MCP servers raises an error.
  • Closes Unresolvable vendor_id / invoice_id in task_data escapes the agent loop's error handling #589.

Root Cause

When task_data contains an unresolvable ID (such as a string like "invalid_vendor_id" or an ID not present in the database), specialized agents' _get_user_prompt() called get_vendor_details or get_invoice_details, which raised exceptions before entering _run_agent_loop's main iteration try block. This resulted in an unhandled exception escaping process(), skipping proper task completion logging, MCP server cleanup, and workflow context clearing.

Changes Made

  1. finbot/agents/specialized/onboarding.py:
    • Explicitly cast vendor_id to int when present in task_data.
    • Catch (ValueError, TypeError) and log a warning if coercion fails or details cannot be retrieved, allowing prompt construction to proceed with empty vendor context rather than crashing.
  2. finbot/agents/specialized/invoice.py:
    • Explicitly cast invoice_id to int when present in task_data.
    • Catch (ValueError, TypeError) and log a warning if coercion fails, allowing prompt construction to proceed with empty invoice context.
  3. finbot/agents/base.py:
    • Moved agent setup (_connect_mcp_servers, prompt generation, workflow context registration) inside a protected try/except block that returns a structured {"task_status": "failed", "task_summary": "Agent setup failed: ..."} and logs task completion.
    • Hardened finally block with separate try/except guards for _disconnect_mcp_servers() and event_bus.clear_workflow_context() to guarantee context cleanup even if MCP disconnect fails.
  4. tests/unit/agents/test_agent_error_handling.py:
    • Added 12 deterministic unit tests covering:
      • Prompt generation with valid, missing, string, and unresolvable IDs for both Vendor and Invoice agents.
      • Full agent execution with unresolvable IDs producing valid completed tasks.
      • BaseAgent setup exception catching and structured failed status return.
      • Context cleanup and MCP disconnection verification on setup failure and when MCP disconnect raises.
      • Stall counter termination behavior.

Verification

  • uv run pytest tests/unit/agents/test_agent_error_handling.py -v: 12 passed in 0.65s.
  • uv run pytest tests/unit/agents/test_base_agent.py -v: 12 passed in 0.60s.
  • uv run pytest tests/unit/agents/test_specialized_agents.py -k "test_sai_von_005_onboarding_tracking" -v: 1 passed.
  • Full test suite: 325 passed, 3 failed, 26 skipped.
  • Lint & Formatting Checks:
    • uv run isort --check-only: Clean.
    • git diff --check: Clean (no trailing whitespace or whitespace errors).

…t#589)

- Gracefully handle missing/unresolvable vendor_id and invoice_id in specialized prompt builders
- Move BaseAgent pre-loop setup into protected execution block
- Return structured task_status='failed' instead of raising unhandled exceptions
- Ensure MCP disconnection and workflow context cleanup in finally block even on setup failure
- Add comprehensive regression tests for agent error handling
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unresolvable vendor_id / invoice_id in task_data escapes the agent loop's error handling

1 participant