Skip to content
S13 — DAN-79

Error State Pattern System

The UX of agentic failure — how the interface contains, communicates, and recovers from agent errors. Three components cover the full failure spectrum: containment (ErrorBoundaryCard), recovery breadcrumb (AgentRecoveryFlow), and partial completion (PartialSuccessPanel).

Color Logic

Error severity maps directly to the three-primary semantic system. Never use raw hex — every color must trace to a --ds-* token.

FATAL

Unrecoverable system failure. Agent cannot proceed. Human cannot fix by approval alone.

RECOVERABLE

Human action resolves the block. Gold signals 'your input required, not a crash'.

TRANSIENT

Auto-recovery in progress. Blue while the agent retries. Resolves without human action.

RECOVERED

Agent or human resolved the error. Green confirms forward motion resumed.

Token Reference

TokenValueUsage
--ds-color-outcome-negative#C62828 / dark: #EF9A9AFatal error border, failed step dot, override button background
--ds-color-validation#C49A1A / dark: #FFD54FRecoverable error border, awaiting-human step, PartialSuccessPanel accent
--ds-color-temporal#2B44D4 / dark: #90CAF9Transient error border, in_progress recovery step dot, retry button
--ds-color-outcome-positive#2E7D32 / dark: #A5D6A7Succeeded step dot and label in AgentRecoveryFlow and PartialSuccessPanel
--ds-color-validation-subtlegold tintHeader background on recoverable error and PartialSuccessPanel header
--ds-color-validation-fgaccessible gold fgText on gold/validation backgrounds
--ds-text-inversewhite / dark: blackText on colored button backgrounds (override, approve)
Component 01

ErrorBoundaryCard

Containment unit for agent errors. Surfaces severity, source, message, optional technical detail, and explicit recovery actions. Never silently swallows errors — every state is visible.

FATAL ERROR
TREASURY-AGENTERR-SIG-0042

Payment Execution Halted

The treasury agent attempted to execute a $2.4M SWIFT transfer but encountered an unrecoverable signature validation failure. The payment has been rolled back. Manual intervention is required to restart the payment cycle.

2026-03-26 14:32:07 UTC
RECOVERABLE — HUMAN ACTION REQUIRED
FX-HEDGE-AGENTSTALE-FX-RATE

FX Rate Data Stale

The EUR/USD rate used for hedging calculations is 4.2 hours old. The agent requires a current rate to proceed with the position sizing recommendation. Approve a rate refresh to continue.

2026-03-26 14:28:44 UTC
TRANSIENT — AUTO-RECOVERY IN PROGRESS
MARKET-DATA-AGENTFEED-TIMEOUT-002

Bloomberg Feed Timeout

The Bloomberg data feed returned a timeout on the bond price query. The agent is automatically retrying with exponential backoff (attempt 2 of 5). No human action required unless all retries are exhausted.

2026-03-26 14:30:01 UTC
Do / Don't
DO
  • Use severity="fatal" only for truly unrecoverable states where no action chain fixes the problem
  • Include a code or trace ID whenever available — operators need it for support tickets
  • Provide at least one explicit action — never leave the operator with no path forward
  • Keep message plain language — operators are humans under stress
DON'T
  • Don't use severity="fatal" for rate limits or timeouts — those are transient
  • Don't use variant="override" (red) for recoverable operations — reserve it for bypassing safety checks
  • Don't put a retry button on a fatal card — it creates false hope
  • Don't suppress the detail prop when debugging info is available
Props
PropTypeDefaultDescription
titlestringShort error title displayed in the card body heading.
messagestringHuman-readable explanation of what failed and why.
sourcestringAgent or system that produced the error (e.g. 'TREASURY-AGENT').
timestampstringISO timestamp or display string shown in the action footer.
severity'fatal' | 'recoverable' | 'transient'Controls border and accent color. fatal=red, recoverable=gold, transient=blue.
codestringundefinedOptional error code or trace ID rendered as a mono chip.
detailstringundefinedRaw technical detail — shown in a collapsible pre block.
actionsErrorAction[][]Recovery actions. Each action has label, variant (retry|escalate|dismiss|override), and onClick.
Component 02

AgentRecoveryFlow

A timeline breadcrumb showing every recovery step the agent attempted after hitting a dead end. Makes the agent's reasoning legible — operators see exactly what was tried, what failed, and what comes next.

LIQUIDITY-AGENT — RECOVERY FLOW
Rebalance EUR liquidity pool by moving €15M from overnight to 3-month instruments
1 OK1 FAILEDRECOVERY IN PROGRESS
Query available 3M instruments14:22:01

Fetched EUR 3-month instrument list from Bloomberg feed

Returned 12 eligible instruments

Execute primary allocation14:22:04

Attempted to allocate €15M to BUND-3M via primary desk

Order rejected — position limit reached

PositionLimitError: BUND-3M current exposure €48M exceeds €50M limit. Delta: €2M headroom only.
Attempt secondary instrument14:22:09

Re-routing €15M to OAT-3M via secondary desk

Partial fill €8.2M — insufficient liquidity for remainder

Split remainder across 2 instruments

Splitting €6.8M residual across ESTR-3M and EU-BILL-3M

Confirm full allocation

Verify total €15M has settled across all instruments

Do / Don't
DO
  • Show every step the agent actually attempted — even failed ones build trust
  • Include the error field on failed steps — raw messages help operators diagnose
  • Use overallStatus="escalated" when the human must make a call, not just approve
  • Keep originalGoal as the agent stated it — don't reframe failures after the fact
DON'T
  • Don't omit failed steps to make the agent look cleaner — that's deceptive
  • Don't use overallStatus="resolved" until all steps are confirmed complete
  • Don't mix recovery steps with business steps in the same flow — keep this to the failure path only
  • Don't show MANUAL OVERRIDE unless you've implemented a real override path
Props
PropTypeDefaultDescription
agentstringAgent that owns the recovery flow.
originalGoalstringWhat the agent was trying to accomplish before it hit the dead end.
stepsRecoveryStep[]Ordered list of recovery steps with status (succeeded|failed|in_progress|pending|skipped).
overallStatus'in_progress' | 'resolved' | 'abandoned' | 'escalated'Controls the top-level accent color and status label.
onOverride() => voidundefinedCalled when the operator clicks MANUAL OVERRIDE.
onDismiss() => voidundefinedCalled when the operator dismisses the flow.
Component 03

PartialSuccessPanel

Surfaces the state "agent completed N of M steps — awaiting human on step K." Gold throughout: this is not an error, it is a handoff. The agent succeeded at its part; the human must complete theirs before the workflow continues.

PARTIAL COMPLETION — HUMAN REVIEW REQUIRED
Quarterly covenant compliance review — Q1 2026
COVENANT-AGENT
3/6
STEPS COMPLETE
Step 1Pull covenant data14:15:02

Retrieved 14 active covenants from credit agreement database

Step 2Run automated checks14:15:08

12 of 14 covenants pass automated threshold checks

Step 3Flag edge cases for review14:15:09

2 covenants require human judgment — leverage ratio and EBITDA definition dispute

Step 4Human review of flagged covenants

Review leverage ratio covenant (current: 3.8x, limit: 4.0x) and confirm EBITDA definition aligns with lender interpretation

YOUR ACTIONReview the two flagged covenants in the attached exhibit and confirm your interpretation. The agent cannot proceed with the compliance sign-off until these are resolved.
Step 5Generate compliance certificate

Draft certificate with your sign-off attached

Step 6Distribute to lenders

Send Q1 certificate to the 3 lender contacts on file

Do / Don't
DO
  • Use gold — this is the validation/quality color, not an error
  • Show ALL steps including completed ones — context for the approver
  • Write humanInstruction as a direct instruction to the specific operator, not a system message
  • Mark remaining steps as remaining, not pending — they haven't failed
DON'T
  • Don't use red for this — partial success is not a failure state
  • Don't have more than one step in awaiting_human at a time — sequence handoffs, don't batch them
  • Don't hide completed steps — the operator needs to see how far the agent got
  • Don't show APPROVE & CONTINUE if you haven't wired up the actual continuation
Props
PropTypeDefaultDescription
agentstringAgent that produced the partial result.
taskstringHigh-level task description shown in the header.
stepsPartialStep[]Steps with status: completed|awaiting_human|remaining|skipped.
onApprove() => voidundefinedCalled when the operator approves the awaited step to continue.
onReject() => voidundefinedCalled when the operator rejects the awaited step.

Anti-Patterns

Silent failure
An agent that fails without surfacing an error destroys trust faster than any loud error could. Operators cannot act on what they cannot see.
Every failure path must render an ErrorBoundaryCard. No swallowed exceptions.
Fatal color for recoverable errors
Red trained to mean 'permanent failure'. Using it for 'rate limit retry' trains operators to panic at a non-crisis.
Use --ds-color-validation (gold) for recoverable, --ds-color-temporal (blue) for transient.
Silent retry
Auto-retrying without showing state removes human oversight from the failure loop. In treasury, this can compound losses.
Show an ErrorBoundaryCard with severity='transient' during any auto-retry. Cancel button required.
Skipping the recovery breadcrumb
Jumping from 'error' to 'resolved' with no visible steps leaves operators unable to audit why the workflow paused.
Use AgentRecoveryFlow for any multi-step recovery. Even a one-step retry should be visible.
Partial success shown as error
Coloring a handoff red trains operators to treat every approval request as a crisis. Gold is the right signal.
PartialSuccessPanel uses --ds-color-validation throughout. Never use ErrorBoundaryCard for handoffs.

Related Patterns