A broker opens a deal and sees no reminders. That could mean there is nothing on the list. It could also mean the system failed to load it.

Those two situations call for different decisions. A reassuring empty state can hide a problem before an AI agent has generated a word.

In a recent engineering review of Clara, we found read paths that could turn a failed request into an empty result. We merged changes to preserve the distinction across affected notes, reminders, email, and priority calculations. This article explains the failure pattern and the regression checks behind that work.

Our earlier articles explored changing facts and tracing decisions back to evidence. This problem starts a step earlier: did the system successfully obtain the evidence it is about to interpret?

How a read failure becomes a business fact

The pattern is easy to introduce. Software asks for a list, catches an error, and returns an empty list so the rest of the screen can keep working.

That fallback removes information. A successful read with zero records and an unsuccessful read now have the same shape. The screen can display “no notes,” and another part of the system can treat the absence as established.

For an agent, this changes the meaning of its input. Imagine an illustrative priority check that considers whether a borrower has an unanswered message. If the message read fails and becomes an empty list, the check may lose the very signal that should keep the file visible. A better prompt cannot recover a failure that the tool response has already hidden.

The error needs to survive the journey from the data source to the caller making the decision.

Completeness belongs in the result

In the affected Clara read paths, the new implementation returns an explicit unavailable error when the requested read cannot be completed. It does not report ordinary success with an empty or shortened list.

These are the distinctions the caller needs:

  1. Empty

    What happened

    The requested read completed successfully and found no matching records.

    What it supports

    An empty result within that request's scope.

  2. Unavailable

    What happened

    The system could not complete the read.

    What it supports

    The current contents are unknown. The caller needs to handle the failure.

  3. Partial

    What happened

    Some records arrived, but the remaining records could not be obtained.

    What it supports

    Some evidence is available. It cannot be treated as the complete requested list.

A later-page failure matters as much as a first-page failure. Successfully reading the first batch does not establish that the remaining records are absent.

The activity reader now advances through pages and rejects a failed later page, a cursor that stops advancing, or a result that exceeds its safety limit. The limit bounds the work; reaching it must not quietly redefine “all records” as “the records we managed to fetch.”

Keep the last good view and explain its limits

An explicit error still needs useful behavior in the app. If a broker already has a successfully loaded list, wiping it out during a temporary refresh failure makes the screen less informative.

The Desktop change preserves the last good notes, reminders, or email when the refresh fails and shows a notice explaining that the refresh did not succeed. If there is no previous content, the screen needs a load-failure state instead of an empty-state conclusion.

The recovery path matters too. A later successful read that really is empty should clear the old list. Keeping cached content forever would create the opposite error: showing work that is no longer present.

Availability and permission are separate questions. A temporary failure to read an authorized file is different from confirmed loss of access. Preserving a previous view during an outage must not become a reason to keep displaying a deal after access has been revoked.

Let dependent decisions wait

Showing a warning addresses the screen. The same failure also needs to reach any calculation that depends on the missing data.

Our priority-refresh change rejects failed or incomplete required inputs before invoking the AI step or saving a replacement priority. This keeps an unsuccessful read from being recorded as a new conclusion about the deal.

That is a narrower and more useful rule than stopping all work whenever anything fails. Work with adequate evidence can continue. A decision that requires the unavailable input should wait, retain its previous status where appropriate, and make the unresolved condition visible.

Test the failure halfway through

The regression coverage uses synthetic data. One activity-reader test creates 451 records, enough to require several pages, and includes records without timestamps. It checks that the reader returns the entire set.

Other tests deliberately fail a later page, exceed a small test safety limit, and repeat a page without advancing the cursor. Each must produce an unavailable result instead of a successful prefix of the list.

Client tests cover retaining a previous list after a failed refresh and clearing it after a healthy empty response. Priority-route tests check that failed source reads do not save a new priority or call the model. Testing only whether an error message appears would miss those downstream effects.

This is evidence about specific read and refresh paths. It does not establish that every integration or installed Clara version handles every outage correctly. The work described here is merged implementation and regression coverage; service deployment and native app releases are separate steps.

For anyone evaluating an agent, a useful test is to interrupt a required read after some data has arrived. Inspect the visible list, the next answer, and any saved decision. Does the system preserve what it knows while admitting what it could not check?

A reliable answer begins with an honest account of whether the evidence was available.

Continue reading

From Evidence to Action: How Agent Decisions Stay Traceable