Skip to content
Insights · AI Agents

When the agent already wrote the row

The agent already wrote a wrong row. Stop the writing tool, keep the trace, and reverse that row yourself. Do not send the model back in to fix it.

Scroll
AI AgentsOct 13, 202612 min readBy Salman Naqvi, Founder & CEO
When the agent already wrote the row

The agent has already written a wrong row into the system of record. Tonight, in this order. Stop the tool that can write, and leave a read in place only if that read cannot change a row. Keep the trace of the write you are worried about: the tool, the arguments, the row, and the value before it if you still have the value. Reverse the row in the system of record by a person, using the product's own correction, not by asking the model to try again. Then count whether this was one row or a loop. If you cannot name the row, you are not in this incident. You are guessing, and sending the model back in would be a second write.

This is the hour after a write has landed. It is not the design argument about how a write should have been idempotent, and it is not the checklist for a wrong answer that was only shown. Identity, freshness, a retry that refunds twice, and a log you can query are decisions you wish were already true. The night that retry has already landed the same action twice is stop the retry that landed twice. The key itself is written down for the design review. Whether the next answer can hurt someone, and whether a person can stop the feature, is a different meeting, and it is allowed to fire on a night when no row has changed. A customer who saw another customer's text is a third meeting. Teams lose the night by holding one call that tries to be all three. A wrong sentence in a chat window does not mean a record moved. A record that moved does not wait for you to decide the prompt was the cause.

The failure is the action, not the sentence. OWASP's 2025 entry on excessive agency describes the grant first: an LLM-based system is often given "the ability to call functions or interface with other systems via extensions (sometimes referred to as tools, skills or plugins by different vendors) to undertake actions in response to a prompt." The decision of which extension to call "may also be delegated to an LLM 'agent'." Then the definition that names tonight: "Excessive Agency is the vulnerability that enables damaging actions to be performed in response to unexpected, ambiguous or manipulated outputs from an LLM, regardless of what is causing the LLM to malfunction." The common triggers it lists are hallucination from a weak prompt or a weak model, and prompt injection, direct or indirect, including from a compromised extension or another agent. The root cause "is typically one or more of: excessive functionality; excessive permissions; excessive autonomy." A note in the same section keeps a neighboring bug separate: "Excessive Agency differs from Insecure Output Handling which is concerned with insufficient scrutiny of LLM outputs" (OWASP, Top 10 for LLM Applications 2025, LLM06:2025). Read that note before you rewrite the prompt. The output can be scrutinized and the write can still have happened. Scrutiny of the next sentence does not undo the row.

The examples are the permissions a founder can check without a framework. Excessive functionality: a tool that was supposed to read documents also modifies and deletes them, or a plugin tried in development was replaced and "the original plugin remains available to the LLM agent." Excessive permissions: an extension meant to read "connects to a database server using an identity that not only has SELECT permissions, but also UPDATE, INSERT and DELETE permissions." Excessive autonomy: a deletion "performs deletions without any confirmation from the user." The prevention list says to minimize the extensions, avoid open-ended ones such as a shell, and require a person to approve high-impact actions. It also says what will not prevent the condition and will only limit the damage: log the activity, and rate-limit so fewer bad actions land before someone notices. Logging is how you see the row. It is not how you remove it. A rate limit you add after the loop has finished does not restore the rows the loop wrote.

A benchmark of tool misuse is not your CRM, and its own sentences do not all match its table. Zhan, Liang, Ying, and Kang built InjecAgent, a benchmark of indirect prompt injection against tool-using agents: 1,054 test cases, from 17 user tools times 62 attacker tools, in two intentions they name direct harm and data exfiltration. They evaluated 30 agents. The abstract says ReAct-prompted GPT-4 is "vulnerable to attacks 24% of the time," and that a setting where the attacker instruction is reinforced with a hacking prompt "nearly" doubles that rate. Table 3 prints ASR-valid, the share of successful attacks among outputs they counted as valid, for agents whose valid rate exceeded 50%. On that table the ReAct-prompted GPT-4 total is 23.6 in the base setting and 47.0 in the enhanced setting. The abstract's 24% is that 23.6 rounded. "Nearly doubling" is the authors' description of 23.6 to 47.0, which is what the body also calls 24% and 47%. A later sentence assigns "3.8% and 6.6% respectively" to fine-tuned GPT-4 and fine-tuned GPT-3.5. The same table's base totals are the other way around: 3.8 for fine-tuned GPT-3.5 and 6.6 for fine-tuned GPT-4. The introduction's "7.1%" for fine-tuned GPT-4 is the enhanced total in that row, not the base. Quote the table when the prose and the table disagree. Direct harm counts as success if the next action is the harmful tool. Data stealing counts only if the agent both extracts and then sends. Invalid outputs are excluded from ASR-valid. The prompt they used already told the agent not to call tools that would harm the user, and the agent was assumed to have run the user's tool correctly before the attack was scored. The cases were generated with GPT-4's help and then edited. Prompted Llama2-70B in the same table is far higher, with base and enhanced totals of 86.9 and 88.2, so 23.6 is not the worst cell and not a property of "GPT-4" as a product name in 2026. This is a research benchmark of synthetic tool calls. It is not a measurement of your customer's database, and it is not a reason to believe a write either will or will not happen tonight (Zhan et al., InjecAgent, Findings of ACL 2024). What you take from it is the definition of success they used: the harmful tool was invoked. Once your tool has been invoked, you are past the benchmark. You are in the system of record.

Stop the tool that writes. Disable the function, the extension, or the credential that can UPDATE, INSERT, or DELETE. Leave a SELECT in place only when you have confirmed the read path cannot call the write path through a second tool the model still holds. OWASP's mailbox example is the shape: a plugin chosen so the agent could read mail also contained send, and the safe version is the one that cannot send. If you cannot remove the write without removing the whole agent, remove the whole agent for the night. That is not a verdict on the model. It is the absence of a separate switch. Do not confuse this with the harm rule for an answer that has not been stored. When to turn a live AI feature off is that rule, and it can apply on a night when every write is still the write you intended. A bad row can land while the sentences look fine. A harmful sentence can be shown while the database is untouched. Write down which one you are in before you change a setting.

Keep the trace before you correct anything. The tool name, the arguments, the row identifier, the value you are about to replace, and the time. If you edit the row first, you have destroyed the before-value the correction was supposed to be measured against. What has to be retained after a wrong answer, when the problem is the answer rather than a row, is what to keep after a wrong AI answer. Use that list if you have it. Do not stop to design a logging platform tonight. A note that names the row is enough to reverse one row. It is not enough to prove the loop stopped. The log of later calls is how you tell those apart, which is why the write tool comes off before you start the archaeology.

A person reverses the row. Open the system of record as a user who is allowed to correct it, and put back the value you wrote down. If the product has an undo that voids the document instead of editing it in place, use that, and keep the void. Do not paste the bad row into a prompt and ask the model to "fix the record." That request is a second invocation of the tool you just decided was unsafe, and InjecAgent's success condition is exactly that the harmful tool gets called. The design property you wanted — a key so the same instruction cannot land twice, and a compensating step when two systems disagree — is what breaks when AI meets a system of record. That article is the review you hold before the tool exists. Tonight the row exists. A design discussion does not remove it, and a second agent call is not a compensating transaction. It is another try.

Then count. One row is an incident you can finish. A loop is the same tool called again after you thought you had stopped it, or a batch that wrote a family of rows from one instruction. Look at the log for that tool across the window, not at the single customer who complained. OWASP's damage limit is a rate limit and a log, and both assume you will look. If the count is larger than the one complaint, the reversal is a list, and the list is work for a person with a query, not work for the model. If you cannot produce the list, say so, and stop claiming the incident is contained. Contained means you know which rows, not that the chat session feels over.

Do not widen the credential to clean up faster. The identity that could UPDATE every table is the excessive permission in the OWASP example, and handing it to the agent "just for the repair" repeats the cause on the repair. A person with a scoped admin login is slower. Slow is the point. A new key, a new tool, or a shell "so we can run a script the model writes" is the open-ended extension the same list tells you to avoid. The script can be yours. The model does not get to run it.

There is a version of this night where calling in a rescue team is the wrong purchase. The row has not been written. You are looking at a design, a demo, or a log from a laptop, and the question is how the tool should have been scoped. That is the design review, and it belongs before launch. Nothing is in production, so there is no system of record to correct. The user's own document was retrieved badly and the answer was wrong, but no downstream record changed. That is what to check when a production RAG answer is wrong, and the model is the last place that list looks. A customer has already seen another customer's data. That is an incident with its own first hour, and reversing one row will not close a leak. You never named the metric the feature had to move, so "a bad row" is the only fact you have. A rescue priced against a metric you have not named is a template, and you should not buy one.

When the row is real and the tool is still the thing that wrote it, the engagement that fits starts by saying what is salvageable. An AI pilot failed to reach production is scoped after an audit, not before it, and the audit is the first one to two weeks of an engagement that runs eight to twelve. The build is unpaid if the metric you agreed does not move. Rollout, when it happens, sits behind a human-review gate. If you do not yet know whether the pilot can be saved, a two-week AI readiness assessment hands you the findings either way. Those are the terms. They are not a promise that every bad row is a rescue, and they are not a rate.

What a write that can be stopped looks like, when one already exists, is a tool that does not have to be the agent. A support agent for a DTC ecommerce brand can look up an order, start a return, or change an address, and those actions sit behind permission guardrails, with a person receiving the conversation when confidence is low. That case is not a story about a corrupted row, and nothing here is a ticket rate, a headcount, or a duration. The shape is the point: there is a write a person can still refuse, so "stop the tool" has a switch that is not the whole product. If your agent's only credential is the one that updates the record, tonight's honest move is to take that credential away, not to hope the next prompt is more careful.

Before midnight, do the four steps in order and write down which one you reached. Name the row. Stop the tool that can write another one. Keep the before-value. Have a person put the row back, and count whether there are more. Do not ask the model to repair the table. The number the engagement has to move, once you are past the alarm and into a rebuild, is the same discipline as AI evaluation and observability: a metric you can miss, checked on a cadence a customer will notice. The row is how you notice. It is not the repair.

Find this useful? Tell Google to show you more of it.

Let's put AI to work in your business.

A 30-minute call. You bring the workflow or the roadmap — we'll tell you what's feasible, what it costs, and what we'd build first.

Book a call→