# Phase 8.11: Tool Chain Error Handling - Implementation Summary
**Status:** ✅ Complete
**Date:** 2026-01-28
**Tests:** 19 new tests, all passing
## What Was Implemented
### 1. Error Classes (`kiwi_mcp/primitives/errors.py`)
Created comprehensive error types with full execution context:
#### `ValidationError`
- Single validation error for a field
- Includes field name, error message, and optional value
- Used to accumulate validation issues
#### `FailedToolContext`
- Context about where a tool chain failed
- Contains:
- `tool_id`: Which tool in the chain failed
- `config_path`: Path to the tool's config file (e.g., `.ai/tools/llm/anthropic_messages.yaml`)
- `validation_errors`: List of validation failures
- `metadata`: Additional context (timestamps, request IDs, etc.)
#### `ToolChainError` (Main Error Class)
- Exception with full chain context
- Contains:
- `code`: Error code (e.g., `CONFIG_VALIDATION_ERROR`, `TOOL_CHAIN_FAILED`)
- `message`: Human-readable description
- `chain`: List of tool IDs in execution path (e.g., `["anthropic_thread", "anthropic_messages", "http_client"]`)
- `failed_at`: `FailedToolContext` with details about the failure
- `cause`: Optional underlying exception
- Methods:
- `_format_message()`: Human-readable formatting for logs
- `to_dict()`: JSON-serializable format for API responses (LLM-actionable)
#### `ConfigValidationError`
- Specific error for tool config validation failures
- Includes tool ID and list of validation errors
### 2. Error Wrapping in Executor (`kiwi_mcp/primitives/executor.py`)
#### Config Validation Error Handling (Line 641-675)
- When runtime parameter validation fails:
1. Builds `ValidationError` objects from validation issues
2. Gets the terminal tool's file path for `config_path`
3. Creates `FailedToolContext` with full diagnostic info
4. Wraps in `ToolChainError` with chain context
5. Returns `ExecutionResult` with error dict in metadata
#### Exception Handling (Line 760-791)
- Catches `ToolChainError` exceptions specifically
- Wraps generic exceptions with chain context:
1. Extracts chain IDs from resolved chain
2. Creates `FailedToolContext`
3. Wraps original exception as cause
4. Returns `ExecutionResult` with error dict
### 3. Comprehensive Tests (`tests/primitives/test_tool_chain_errors.py`)
19 test cases covering:
**ValidationError Tests (2 tests)**
- Basic creation
- Creation with value
**FailedToolContext Tests (3 tests)**
- Minimal context creation
- Context with validation errors
- Context with metadata
**ToolChainError Tests (11 tests)**
- Basic error creation
- Error with underlying cause
- Formatted error message
- Formatted error with cause
- Serialization to dict
- Dict serialization with cause
- LLM-actionable format validation
- Exception behavior (is-exception, raiseable)
- Config validation error tests
- Error context integration (2 tests)
**Integration Tests (3 tests)**
- Complete error context flow (validation → serialization)
- Multiple errors in chain
### 4. API Exports
Updated `kiwi_mcp/primitives/__init__.py` to export:
- `ToolChainError`
- `FailedToolContext`
- `ValidationError`
- `ConfigValidationError`
## Files Modified/Created
| File | Changes | Status |
|------|---------|--------|
| `kiwi_mcp/primitives/errors.py` | NEW - Error classes | ✅ |
| `kiwi_mcp/primitives/executor.py` | Extended with error wrapping | ✅ |
| `kiwi_mcp/primitives/__init__.py` | Added error exports | ✅ |
| `tests/primitives/test_tool_chain_errors.py` | NEW - 19 tests | ✅ |
| `tests/primitives/test_chain_execution.py` | Updated fixture (removed mock_registry param) | ✅ |
## Example Error Response
When a tool chain fails during execution, the response includes structured error context:
```json
{
"success": false,
"error": "[CONFIG_VALIDATION_ERROR] Configuration validation failed for 'anthropic_messages': ...",
"metadata": {
"error_context": {
"code": "CONFIG_VALIDATION_ERROR",
"message": "Configuration validation failed for 'anthropic_messages': ...",
"chain": ["anthropic_thread", "anthropic_messages", "http_client"],
"failed_at": {
"tool_id": "anthropic_messages",
"config_path": ".ai/tools/llm/anthropic_messages.yaml",
"validation_errors": [
{
"field": "config.model",
"error": "required",
"value": null
},
{
"field": "config.max_tokens",
"error": "must be >= 1",
"value": 0
}
]
},
"cause": null
}
}
}
```
## LLM-Actionable Error Format
The error dict structure enables LLMs to:
1. **Identify what failed**: Error code + message
2. **Understand where it failed**: Chain path + tool_id + config_path
3. **Know how to fix it**: Validation errors with field names and requirements
4. **Trace root causes**: Underlying exception included as cause
## Success Criteria Met
- ✅ `ToolChainError` includes full context (chain, config_path, validation errors)
- ✅ Errors are wrapped at execution layer
- ✅ Config validation failures generate structured errors
- ✅ Error responses are JSON-serializable and LLM-actionable
- ✅ Comprehensive test coverage (19 tests)
- ✅ All tests passing (54 tests in related files)
## Next Steps
Phase 8.12 will add cost tracking validation, which can leverage the same error handling infrastructure to provide clear diagnostics about missing or invalid cost declarations.