DEV Community

imokokok
imokokok

Posted on

Recovering an AI Agent’s Transaction Observation After a Timeout

An agent submits a transaction, receives a transaction hash, and starts waiting for execution evidence.

Then the client’s wait expires.

What should the application preserve, and how can it continue observing the original transaction after a restart?

Here is a small recovery example using PriorSeal’s TypeScript SDK.

1. Persist the operation identifiers

Save the original transaction hash, chain ID, and authorization ID when they become available.

When observeExecution() returns an observationJob, persist its jobId before continuing to wait.

These identifiers let a restarted process locate the original operation. Store them in durable storage appropriate for your deployment.

If the initial observation response was lost before a job ID was saved, the example below cannot resolve that missing identity. Reconcile the original operation using its known transaction and authorization references.

A timeout alone should never trigger a new trade.

2. Resume an existing observation job

This example requires an observation job that already exists. It only polls that job; it does not create an authorization, sign a transaction, or broadcast one.

Use Node.js 22 or later:

npm install priorseal-sdk
npm install --save-dev tsx
Enter fullscreen mode Exit fullscreen mode

Save this as resume-observation.mts:

import {
  createPriorSealClient,
  PriorSealApiError,
} from 'priorseal-sdk';

const jobId = process.env.PRIORSEAL_JOB_ID?.trim();
if (!jobId) {
  throw new Error('Set PRIORSEAL_JOB_ID to an existing observation job');
}

const priorseal = createPriorSealClient({
  baseUrl: 'https://priorseal.xyz',
});

try {
  const job = await priorseal.waitForObservationJob(jobId, {
    timeoutMs: 30_000,
    pollIntervalMs: 2_000,
  });

  console.log(JSON.stringify({
    jobId: job.jobId,
    jobState: job.state,
    observation: job.observation,
    result: job.result,
    error: job.error,
  }, null, 2));
} catch (error) {
  if (
    error instanceof PriorSealApiError &&
    error.code === 'OBSERVATION_WAIT_TIMEOUT'
  ) {
    console.error(
      'Wait expired. Preserve this job ID for another observation attempt:',
      jobId,
    );
    process.exitCode = 2;
  } else {
    throw error;
  }
}
Enter fullscreen mode Exit fullscreen mode

Run it with your saved job ID:

PRIORSEAL_JOB_ID='your-existing-job-id' npx tsx resume-observation.mts
Enter fullscreen mode Exit fullscreen mode

The polling interval and wait duration are example settings.

If the wait expires again, preserve the same job ID. Schedule another observation attempt according to your application’s recovery policy.

3. Inspect the returned state

waitForObservationJob() returns when the job reaches COMPLETED, UNDETERMINED, or FAILED.

Those are observation-job states. Your application must inspect the execution observation, available result, receipt, and error separately.

A completed observation job does not by itself establish that a trade succeeded or complied with its authorization. A receipt may also require independent verification against trusted issuer keys and additional chain-state checks.

Keep pending, reverted, reorged, and uncertain execution states explicit in your records.

4. Keep new execution behind its own authorization checks

Recovering historical evidence does not extend an authorization window.

If the business needs a new transaction, the executor must apply the relevant submission-time policy and obtain valid authorization for that action.

The recovery worker above has a narrower responsibility: continue investigating an existing operation.

A small recovery checklist

Before deploying an agent, check that:

  • Transaction and authorization identifiers survive a restart.
  • Observation job IDs are saved as soon as they are returned.
  • Client wait timeouts preserve the existing operation identity.
  • Observation-job state and execution outcome are evaluated separately.
  • New transactions require their own applicable policy and authorization checks.

Which part of your agent’s recovery state currently exists only in memory?

References

Top comments (0)