When an AI query fails,
the next attempt needs a clean start.
An AI agent can correct a query and still fail on its second attempt. The database session may still be in a failed transaction. Recovery has to happen in the application as well as in the model’s reasoning.
Discuss your systemBy Sourish Sarmah · . Informed by Sourish’s prior work at Agentic Private Markets. This was employment experience, not a Meld Origins client engagement or endorsement.
The failure behind
the failure.
Consider a generic analytics assistant asked to summarize orders by region. Its first query uses a column that does not exist. The database rejects it, and the assistant receives enough information to try a different column. The corrected query looks reasonable, yet execution fails again.
In PostgreSQL, a statement error inside an explicit transaction can leave that transaction aborted. Sending another ordinary statement through the same transaction does not repair it. The application must end the failed transaction, or recover to an appropriate savepoint, before continuing. The transaction boundary determines which recovery is valid.
The useful debugging question is therefore twofold: was the generated query wrong, and is the execution environment ready for another attempt?
A concrete piece
of prior work.
In his prior work at Agentic Private Markets, Sourish contributed changes to the execution path for AI-generated queries, including rollback after a database failure and recording execution outcomes. That work informs this note’s focus on recovery between attempts.
The example here is generic. The guidance describes broadly applicable engineering decisions; it does not reproduce the employer’s code, data model, internal configuration or operating results.
Give each attempt
a deliberate boundary.
For an independent read-only query tool, a short transaction can make the lifecycle easier to reason about: start the attempt, run the permitted query, collect its result and close the transaction. If execution fails, recover or discard that session before returning control to the agent.
The component that owns the transaction should own that decision. Rolling back a shared transaction can also discard unrelated pending changes. When work must remain inside a larger transaction, a deliberately placed savepoint may provide a narrower recovery boundary. It still needs to be tested with the actual database driver and session lifecycle.
If recovery itself fails, do not reuse the session as though it were healthy. Report a controlled failure and release the damaged resource. A retry budget does not make a broken connection usable.
Retry the right
kind of failure.
Separate correction from repetition
A missing column may call for revised SQL or better schema context. A permission denial should stop the action or request authorized access. A transient connection failure may justify a bounded retry. Repeating every failure follows none of those distinctions.
Keep permissions outside the model
Recovery does not validate a query or authorize access. Restrict database privileges, enforce the caller’s data scope and apply execution limits independently. Every corrected query must pass the same checks as the first.
Set an overall budget
Limit attempts and elapsed time, and return a clear outcome when the budget is exhausted. For tools that write data, also account for uncertain completion and duplicate effects before retrying. This read-query example does not establish safe write retries.
Test the second
attempt explicitly.
A useful integration test deliberately submits an invalid read query, then a valid one through the intended recovery path. Check that the second query executes, the first failure remains visible in the attempt history, and resources are released afterward.
Additional cases should cover a query timeout, failed rollback, denied access, cancellation and an exhausted retry budget. If savepoints are used, verify which earlier changes survive. These are suggested checks for a product using this pattern, rather than a claim about a particular deployment’s test results.
Operational traces should distinguish query rejection, database failure, recovery failure and successful completion. Record timings and attempt identifiers while limiting sensitive query text and result data. The practical objective is to understand why an attempt failed without unnecessarily copying business data into logs.
Related work
and references.
For the surrounding permission boundary, read our enterprise Text-to-SQL MCP note. For external work that shares the event loop, read the async research note.
Building a data assistant or adding AI to an existing product? Explore backend engineering or discuss the workflow.
