An AI agent can make a perfectly reasonable decision and still get things wrong. Imagine an agent managing a crypto wallet. It checks the balance, reviews a transaction request, verifies that the amount is within the permitted limit, and prepares a transfer. Everything looks fine. The agent has followed its instructions, the calculations are correct, and the transaction appears to satisfy the application's rules.
But there is a problem. Another transaction has already moved some of the funds, and the application's internal balance has not been updated yet. The agent is working with yesterday's reality, even though the data it received looks legitimate.
This is the kind of problem that interests me when thinking about production AI systems. We spend a lot of time discussing better models, retrieval quality, context windows, and tool calling. Those things matter, but they do not solve a more basic problem: what happens when the information an agent relies on no longer reflects the system it is operating in?
Blockchain applications make this problem particularly interesting. Data moves through RPC providers, event subscriptions, indexers, databases, and caches before it reaches the application that needs it. Every component has its own timing and failure modes. By the time an AI agent uses that information, the underlying blockchain state may have changed.
The agent does not necessarily know that. It can only work with the information available to it. An AI agent is only as reliable as the state it observes and the system's ability to keep that state accurate.
This is not just a problem for crypto trading bots. It matters anywhere an autonomous system uses blockchain data to make decisions, including treasury management, decentralised finance, token transfers, and smart contract automation.
The difference between a blockchain event and an application state
Let's start with something simple. A user transfers tokens from one wallet to another. The blockchain records the transaction, and a corresponding event can be emitted by the token contract. An application listens for that event and updates its database so that the user's portfolio reflects the change.
In an ideal world, the event arrives once, gets processed immediately, and the database always reflects the latest state.
Real systems are rarely that tidy. The same event might be delivered more than once. An indexing service might fall behind. A network interruption might delay processing. Two workers might process related events in the wrong order. A block that the application previously observed might later be replaced during a chain reorganisation.
None of these situations necessarily means the blockchain itself is broken. The problem is that the application can build an incorrect picture of the blockchain from the information it receives.
An event tells us that something happened within a particular chain of history. Application state is the result of interpreting those events, applying business rules, and maintaining a representation of the current situation.
Those are two different things. Consider an application that maintains token balances by adding incoming transfers and subtracting outgoing transfers. If it processes an incoming transfer twice, its internal balance increases twice even though the wallet received the tokens only once. The event can be genuine. The processing can still be wrong.
Now introduce an AI agent that uses the application's balance to decide whether it can execute a payment. The agent may receive an incorrect balance, calculate the requested amount correctly, and produce a transaction that passes the checks it was given.
The failure did not begin with the model's reasoning. It began with the state supplied to the model. This distinction is important because improving the model will not fix a broken state pipeline. The application needs to establish whether the information it provides is trustworthy before asking the agent to act on it.
How a small data problem becomes a financial problem
Consider a hypothetical treasury agent who handles routine payments. Its application maintains an internal balance of 2,000 tokens. A transfer of 600 tokens is submitted from the wallet. The blockchain processes the transfer, but the event consumer has not yet updated the database.
Meanwhile, the agent receives a request to transfer another 1,700 tokens. The agent queries the database, sees a balance of 2,000 tokens, and concludes that the payment is affordable. Its reasoning may be completely correct based on the information it received. But the actual available balance may now be only 1,400 tokens.
The application has given the agent a number without making clear that the number represents an earlier state. A different failure could produce the opposite result. If an event is missed, the application might understate the balance and reject a legitimate payment.
Both problems come from the same assumption: that receiving and processing blockchain events automatically guarantees accurate application state. It doesn't.
For a read-only assistant, an incorrect balance may result in a misleading answer. For an agent that can initiate transactions, the same discrepancy can lead to a financial action that cannot easily be reversed.
That changes how we should approach state management. It should not be treated as a background implementation detail. It needs to be part of the reliability controls surrounding the agent.
Five ways blockchain applications can lose track of state
There are several common failure modes worth understanding before designing the solution.
1. Duplicate events
Event consumers sometimes retry work when acknowledgements are delayed, network connections fail, or a service restarts. If the application applies the same business operation every time it receives a message, a retry can create a duplicate effect.
A blockchain event can usually be identified using a combination of fields such as the chain ID, block hash, transaction hash, and log index. These fields can help the application recognise that it has already processed a particular event.
However, checking whether an event has been seen is not enough if the check and the resulting database update can happen independently. Two workers might receive the same event simultaneously, and both apply it. The application needs a concurrency-safe way to record the event and apply its effect.
2. Events arriving out of order
Imagine an application processing a deposit followed by a withdrawal. If the withdrawal is processed first, a balance projection that relies on sequential updates may temporarily or permanently become incorrect.
Some events can be processed independently. Others require ordering guarantees or version checks. The important decision is whether the application's state model can tolerate reordering. If it cannot, the consumer must enforce the required ordering or rebuild the state from a reliable reference.
3. Delayed indexers
Indexers make blockchain data easier to query by turning low-level events into structured information. They are useful, but they are still processing systems with their own progress and latency.
An indexer can return a successful response while remaining behind the relevant chain state. This becomes especially problematic when an agent combines information from different sources. A wallet balance might come from a recent RPC call, while liquidity data comes from an indexer that has not yet processed the latest blocks.
Both responses may be valid for their respective observation points, yet the combined view may no longer describe a consistent situation.
4. Chain reorganisations
Some blockchain networks can replace previously observed blocks before the relevant state reaches the required finality threshold. If an application has already applied events from a displaced block, its internal state may contain effects that no longer belong to the canonical chain history.
The application needs a way to identify affected records and reverse or rebuild the relevant projection. Treating every observed event as permanently final is not sufficient for systems that depend on accurate chain history.
5. Concurrent updates
Two workers might read the same database balance, calculate different updates, and then overwrite each other's changes.
This is a familiar distributed-systems problem known as a lost update. It can happen even when the blockchain events are genuine and delivered correctly. The database and processing architecture need appropriate transaction boundaries, locking, version checks, or other concurrency controls to prevent it.
These failures have different causes, but they all demonstrate why event delivery and state correctness must be treated as separate concerns.
Building a reliable state pipeline
If I were designing this system, I would separate event ingestion, state processing, validation, agent reasoning, and transaction execution. The goal would not be to introduce as many services as possible. It would be to make each responsibility clear enough that a failure in one stage does not silently corrupt everything that follows. Here is the basic flow:
Blockchain | v RPC and Event Listener | v Event Validation | v Durable Event Storage | v Idempotent Event Processor | v Versioned Application State | v Reconciliation and Validation | v AI Agent | v Policy Checks and Revalidation | v Transaction Execution | v Receipt and Outcome Verification The event listener captures changes from the blockchain. Durable storage preserves enough information to recover from processing failures. The event processor handles duplicates and applies changes according to the application's consistency rules.
The state layer maintains a queryable representation of the data. A reconciliation process checks whether that representation still agrees with an appropriate authoritative source. Only then does the agent use the information to propose an action. Before the action is executed, the system validates the assumptions that matter for that transaction. Once execution is complete, it verifies the result and updates the workflow state.
A small application might implement several of these responsibilities within a single service. A larger application may separate them into different components. The important part is the sequence and the guarantees, not the number of boxes in the architecture diagram.
Making event processing idempotent
One of the most useful techniques in event-driven systems is idempotency. An operation is idempotent when repeating the same logical operation does not create an additional unintended effect.
For blockchain event processing, the application can construct an event identity and use it to prevent the same event from being applied more than once. Here is a simplified Python example:
def event_id(event): return ( event["chain_id"], event["block_hash"], event["transaction_hash"], event["log_index"], ) def process_event(event, store): key = event_id(event) if store.is_event_applied(key): return "duplicate_ignored" store.apply_event_and_mark_processed( key=key, event=event, ) return "applied" This illustrates the pattern rather than a complete production implementation. The storage layer must ensure that applying the event and recording it as processed are atomic, or otherwise protected against concurrent workers.
A database uniqueness constraint combined with a transaction is one common approach. Without such protection, two workers could both check for the event, both conclude that it is new, and both apply the change. There is another limitation worth mentioning. Including the block hash in the event identity helps distinguish events from different block histories, but it does not automatically handle chain reorganisations.
If a previously processed block is displaced, the application still needs to invalidate or reverse the state derived from that block. Idempotency prevents duplicate effects. It does not guarantee that an event remains part of the canonical chain.
That distinction is easy to miss when reliability patterns are treated as universal solutions rather than controls for specific failure modes.
Your application state should carry its own history
Many applications store a balance or a position without recording enough information to explain how the value was produced. That works until something goes wrong.
Suppose an agent reads a balance of 1,250 tokens. An engineer investigating a later failure needs to know whether the balance came from a recent chain query, a cached response, or an indexer that was several blocks behind. The number alone cannot answer that question. I would associate a critical state with metadata describing its origin and processing history. Depending on the application, this might include the chain ID, block number, block hash, indexing checkpoint, projection version, and last successful reconciliation. For example:
{ "token": "USDC", "balance": "1250.00", "chain_id": 1, "projection_version": 17, "indexed_through_block": 24000100, "last_reconciled_at": "2026-10-29T05:30:00Z", "consistency_status": "verified" } These values are illustrative. A timestamp alone does not prove freshness, and the status should only be marked as verified after a defined validation procedure has succeeded.
For a system that depends on a particular chain history, the block hash is also useful because different blocks can exist at the same height. This metadata makes it possible to ask better questions. Which state did the agent observe? How far had the indexer progressed? Which version of the processing logic produced the value? Had the application reconciled the projection against an appropriate reference?
It also helps distinguish between historical information and the current state. An agent might need historical balances to explain how a portfolio changed over time. That information can remain useful indefinitely as historical evidence. It should not automatically be reused as the current balance for a new transaction.
The application needs to understand what a value represents and whether it remains suitable for the task at hand.
Reconciliation catches the mistakes that normal processing misses
Even a carefully designed event processor can encounter missed updates, software defects, or unexpected infrastructure failures. Reconciliation gives the application a way to detect when its internal state no longer agrees with the relevant blockchain state. For a simple token balance, the application might compare its local projection with a balance obtained through an appropriate contract query. For a more complex lending position, it may need to query several contract values and reproduce the protocol's calculations.
The comparison must use equivalent state references. A local projection processed through block 100 may legitimately differ from a query against block 105 because additional transactions occurred in the meantime.
The application should first establish which blocks the projection has processed and which state the comparison represents. If a discrepancy is found, the system can investigate the event history, replay events from a known checkpoint, or rebuild the projection. It should not blindly overwrite the local value with a new query result without understanding the difference.
Reconciliation also needs to reflect the application’s risk profile. A reporting dashboard may tolerate some indexing delay. An agent preparing a high-impact transaction may require a more current state check before it is authorised to proceed.
This does not mean every model call needs to trigger a full reconciliation. A more practical design uses efficient projections for ordinary analysis and stronger validation at the point where a consequential action is authorised. That balance keeps the system usable without treating performance as a reason to ignore state integrity.
What happens when a transaction times out?
State management becomes even more important when an AI agent submits a transaction and does not receive a clear response. Imagine the agent sends a transaction through an RPC provider. The request times out. The agent does not know whether the transaction reached the network. If it assumes that the transaction failed and immediately submits another one, it could create an unintended duplicate operation.
A timeout tells us that the response was not received within the expected period. It does not prove that the underlying operation never happened. The application needs a durable transaction record that survives agent restarts and uncertain network conditions. That record should track the transaction hash when available, chain ID, sender, nonce, where applicable, submission attempts, observed receipts, and current lifecycle status.
The lifecycle might move through states such as proposed, validated, authorised, submitted, included, confirmed, and verified. An uncertain submission should have its own explicit state rather than being silently marked as failed. When a timeout occurs, the recovery process should inspect the original transaction and reconcile its status before deciding what to do next. A transaction might still be pending. It might have been included in a block. It might have reverted. It might have been replaced by another transaction using the same nonce. Those outcomes require different responses.
The agent's conversational memory should not be the authoritative source of transaction status. That status belongs in a durable application state, backed by the available transaction and receipt evidence. This is the same principle that applies to other autonomous workflows: a system must distinguish between an operation that failed and an operation whose outcome is not yet known.
Context engineering starts with a trustworthy state
This is where blockchain state management connects directly to my interest in context engineering. An agent's context is often treated as information assembled from documents, databases, tools, and memory. But context quality depends on more than relevance. The information must also be suitable for the decision the agent is about to make. A retrieved balance can be relevant but outdated. A protocol event can be accurate but incomplete. A stored transaction status can describe an earlier stage of execution.
If the agent cannot distinguish these conditions, it may reason correctly from information that should no longer be trusted. I would separate the workflow into three stages.
Observe. Retrieve state with enough metadata to establish its source, relevant block reference, and validation status.
Decide. Allow the agent to interpret the validated context and propose an action.
Authorize. Recheck critical assumptions and policy constraints before allowing the action to execute.
Suppose an agent prepares a swap based on a particular liquidity observation. The pool changes while the agent is reasoning. The proposal may no longer satisfy the conditions under which it was created. The runtime should detect that the relevant assumptions have expired and require fresh validation. It should not simply ask the model whether it is still confident. Confidence does not establish that the blockchain state remains unchanged.
This separation allows the agent to focus on interpreting goals and proposing actions, while the application remains responsible for state integrity and authorisation. It also makes the system easier to test. We can evaluate the agent's planning separately from the controls that prevent an invalid proposal from reaching execution. A capable agent should make useful decisions. A reliable application should know when those decisions are no longer safe to act upon.
Testing whether the system can recover
A state-management design should be tested under failure conditions, not only against a clean stream of events. I would build a test suite that deliberately introduces duplicate delivery, delayed events, out-of-order processing, indexer lag, database concurrency conflicts, and uncertain transaction submissions. The system should demonstrate that it can detect these conditions and either recover or stop safely.
| Test scenario | Expected behavior |
|---|---|
| The same event arrives twice | The business effect is applied once |
| Events arrive out of order | Ordering rules are enforced, or the state is reconciled |
| The indexer falls behind | Stale data is identified before a sensitive action |
| A processed block is reorganised | The affected projection is invalidated or rebuilt |
| Two workers update the same record | Concurrency controls prevent lost updates |
| An RPC submission times out | The original transaction is reconciled before retrying |
| A balance differs from an authoritative state | The discrepancy is flagged, and the proposal is revalidated |
| The application restarts mid-workflow | Processing resumes from a durable state |
These tests should be reproducible in a local environment or controlled test network. I would also measure duplicate suppression, projection divergence, reconciliation recovery time, unresolved transaction frequency, and the number of invalid proposals that reach the execution boundary.
For high-impact actions, the goal should be to prevent known state-integrity violations from resulting in unauthorised execution. The precise thresholds depend on the application. A reporting service and an autonomous treasury system should not necessarily have the same latency or consistency requirements. What matters is that the requirements are explicit and that the tests demonstrate whether the implementation meets them.
Observability makes state failures easier to explain
Even with good event processing and reconciliation, failures can still occur. Engineers need to understand when the application has stopped representing the state it claims to represent. For every important projection, I would monitor its processing checkpoint, indexing lag, last successful reconciliation, and number of events awaiting processing.
For every consequential agent decision, I would preserve the relevant observation references, projection version, policy result, and transaction lifecycle identifier. This makes it possible to trace an incorrect decision back to the stage where the state became unreliable.
Was an event never processed? Did two workers apply the same update? Did the indexer fall behind? Did the agent reuse an outdated observation? Did the execution layer fail to revalidate the balance? These are different problems, and the system should provide enough evidence to distinguish them.
Observability and state management serve different purposes. State management determines how the application constructs and maintains its view of reality. Observability helps engineers detect and explain when that view becomes unreliable. Together, they make the system easier to operate and safer to change.
Conclusion: better reasoning cannot repair a broken state
As AI agents move into applications that can transfer assets, execute smart contracts, and manage decentralised workflows, the quality of their decisions will depend heavily on the state presented to them. A blockchain event may be valid. An indexer may return a successful response. A database query may complete without error. Yet the combined application state can still be incorrect.
That is why reliable autonomous systems need more than capable models. They need idempotent event processing, versioned state projections, reconciliation, chain-aware recovery, durable transaction lifecycles, and execution-time validation. These practices are not unique to blockchain, but blockchain makes their importance particularly clear.
The objective is not to eliminate every delay or force every application to wait for the strongest possible confirmation. It is to understand the guarantees required for each operation, detect when those guarantees are no longer satisfied, and prevent unsafe actions from proceeding.
For me, this is the broader connection between context engineering and distributed-systems reliability. An agent's decision is only as good as the information it receives, and that information is only useful when the application understands what it represents.
Reliable AI is not just about making better decisions. It is about ensuring that decisions are based on a trustworthy state and preventing them from being executed when that state can no longer be trusted. That is the engineering work that needs to happen before autonomous agents can be trusted with more consequential responsibilities.
