Skip to main content

Primary Error: Mixed Abort States

The only specific error you need to handle when implementing Human-in-the-Loop approvals is attempting to mix ABORTED_WITH_FEEDBACK states with APPROVED or DENIED states in a single batch.

Error Response

When you submit a batch with mixed abort states, you’ll receive an error response through the normal agent response mechanism:
{
  "error": "Invalid approval batch: cannot mix ABORTED_WITH_FEEDBACK with other approval states",
  "batchId": "batch_456"
}

Client-Side Prevention

The best approach is to prevent this error client-side through validation:
function validateBatchStates(decisions: Map<string, ApprovalState>): ValidationResult {
  const states = Array.from(decisions.values());
  const hasAbort = states.includes('ABORTED_WITH_FEEDBACK');
  const hasOtherStates = states.some(state => state !== 'ABORTED_WITH_FEEDBACK');
  
  if (hasAbort && hasOtherStates) {
    return {
      valid: false,
      error: 'Cannot mix ABORTED_WITH_FEEDBACK with APPROVED or DENIED states'
    };
  }
  
  return { valid: true };
}

function onSubmitBatch(batchId: string) {
  const decisions = getBatchDecisions(batchId);
  const validation = validateBatchStates(decisions);
  
  if (!validation.valid) {
    showError(validation.error);
    return;
  }
  
  submitBatch(batchId, decisions);
}

Other Error Scenarios

All other error scenarios (network failures, missing fields, incomplete batches, etc.) are handled through the normal agent response system. The agent will communicate these errors to the user naturally through conversation rather than specific error codes.

Network Connection Handling

For connection issues with the SSE stream, implement basic reconnection logic:
class ApprovalEventHandler {
  private eventSource: EventSource | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 3;
  
  connect(threadId: string) {
    this.eventSource = new EventSource(
      `${API_BASE_URL}/api/assistants/threads/${threadId}/stream`,
      { headers: { 'Authorization': `Bearer ${API_KEY}` } }
    );
    
    this.eventSource.onerror = () => {
      if (this.reconnectAttempts < this.maxReconnectAttempts) {
        this.reconnectAttempts++;
        setTimeout(() => this.connect(threadId), 1000 * this.reconnectAttempts);
      } else {
        showToast('Connection lost. Please refresh the page.', 'error');
      }
    };
    
    this.eventSource.onopen = () => {
      this.reconnectAttempts = 0;
    };
  }
}

Next Steps

  • See Implementation Examples for complete error handling implementations
  • Focus on client-side validation to prevent the mixed abort states error
  • Let the agent handle all other error communication naturally
I