17 Ways Your AI Agent Quietly Lies to You
Field notes from two weeks of running an autonomous agent on real money Base64 uploads fail without an error Uploading a binary file (xlsx, zip, PDF) by having the model emit a base64 string fails above a certain size. Not with an exception — with slightly wrong content. Observed: at ~37,000 charact

Field notes from two weeks of running an autonomous agent on real money Base64 uploads fail without an error Uploading a binary file (xlsx, zip, PDF) by having the model emit a base64 string fails above a certain size. Not with an exception — with slightly wrong content. Observed: at ~37,000 characters, at ~11,564 characters, and at 22,108 characters. Below roughly 6,000 characters it was reliable. The dangerous part: a corrupted base64 string still decodes successfully. It produces a valid file with wrong bytes inside. Nothing errors. The agent reports "uploaded and verified." In practice this meant a spreadsheet that opened to a blank grid, and an invoice image where the header was crisp and everything below it was grey mush. What to do: Never have the model reproduce a long base64 string. If the platform saved the download to a local file, decode it programmatically instead. For anything larger, see #2. "Verified" usually means "the call didn't error" The agent wrote "verified" in its report. What it had actually checked was that fileSize matched and the upload call returned success. It had not opened the file. Same-size, wrong-content is the most common corruption mode there is. File size is close to worthless as a verification signal. What to do: Define verification explicitly, per file type. For text: read it back and diff against the source. For spreadsheets: export to CSV and compare totals. For images and scanned documents: render and look at it — check that specific fields are legible, not that the file opens. The rule that fixed it: "Do not write 'verified' unless you state what you compared." Two nearly-identical files uploaded in sequence swap contents Two payment vouchers, same template, different names and amounts. Uploaded one after the other. Three times in a row, the file named for the second worker contained the first worker's data. The cause appears to be that both files share a long identical byte prefix. The fix was to inject a unique marker early in each file, before the divergence point. What to do: When generating a batch of similar documents, make them differ early. Then verify each one by a content string unique to it — not by size, and not by "the upload succeeded." Text corruption in natural language, not just binary Uploading a plain Hebrew document, one word appeared that was not in the source. Another time a single word came out with mixed Hebrew and Latin characters inside it. Both survived the upload. Neither triggered any error. This is rarer than binary corruption, but it means no reproduction of long content is fully trustworthy — not even plain text. What to do: Byte-for-byte comparison after upload, or a hash. For long documents, this is the only reliable check. Part II — The Reasoning Failures The agent computed a total from a document it never read An email said: three amounts, 216 + 864 + 2,610. The agent summed them, wrote "total outstanding: 3,690," and recommended approving payment. The actual total was 64,118.41. The real figures were in a PDF attachment. The agent's own log said, one line earlier, "attachment not read." It summed what it could see anyway and presented it as the answer. This is the most dangerous failure in the list, because the output was fluent, confident, and off by a factor of seventeen. What to do: Make it a hard rule — never infer from a source you did not read. When part of the information is in an unread attachment, report three things: what is known, what is not known, and why it could not be read. Never a number. It cannot read Gmail attachments at all — and won't tell you There is no tool that downloads attachment content from Gmail. The tools return metadata only: filename, ID, MIME type. An agent that doesn't know this will summarize an email as though it read the attachment. What to do: Make the limitation explicit in the agent's instructions. The required behavior: name the attachments, state that they were not read, and ask the user to save them to cloud storage — from which they can be read. "No reply yet" — when the reply arrived an hour later, elsewhere The agent reported that a request had gone unanswered for six days. The answer had arrived roughly one hour after the request. It came from quickbooks@notification.intuit.com, in a completely separate thread, with a different subject. The agent had searched only inside the original thread. Business replies routinely arrive from a third-party system — invoicing portals, billing platforms, e-signature services, payment providers. Structurally unrelated. Substantively, the answer. What to do: Before concluding "no reply," require three searches: by the company name, by keyword (invoice / receipt / statement), and by date range around the request. If those searches weren't run, the only permitted phrasing is "no reply found in the thread itself; other channels not checked." That's a statement about what was checked — not a conclusion. Label ID in a search query returns empty — never an error The agent tagged threads with a Gmail label to track them, then searched with label:Label_9. Result: zero threads. Every time. Gmail search requires the label's display name, not its ID. The ID is correct for applying a label and wrong for searching — and the failure mode is an empty list, indistinguishable from "nothing to report." The entire tracking mechanism had never worked. It reported "nothing new" on every run, and looked healthy doing it. What to do: When a search that should return results returns empty, treat it as suspect before treating it as an answer. And test tracking mechanisms with a case you know exists. It has no sense of elapsed time The user mentioned a meeting "tomorrow morning." Later in the same conversation, the agent referred to the meeting as still being tomorrow. It was now the next day. The meeting was in ninety minutes. An agent does not experience duration. Between one message and the next, minutes or days may have passed, and nothing in its context distinguishes them. What to do: Require an actual clock check — a shell call, a tool call, anything real — at the start of every response and every scheduled run. Never carry "today" or "tomorrow" forward from earlier text. Related: operations after midnight UTC were logged under the previous day in local time. Pick a business timezone and enforce it everywhere. Part III — The Structural Failures Rules stored by file ID break the moment a rule is updated The agent's instructions referenced its configuration files by ID. One instruction said: always update the file map after creating a file. Updating a file produces a new ID. So the rule "always update the map" guaranteed that every pointer to the map would break. It broke all three scheduled tasks at once, within hours. What to do: Reference configuration by name, not ID. Names are stable; IDs are not. And add: if a name search returns more than one result, stop and report — you have a shadow copy (#11). Opening a CSV in the Sheets UI silently creates a second file Open a raw CSV through Google Sheets and Drive does not edit it. It creates a new, separate Sheets file with the same name. Two files. Identical names. Different IDs. Different contents from that point on. This happened twice. At one point there were three live copies of the same cash flow, each with a different balance, and a link that led to whichever one you happened to have. What to do: Create anything that will be opened in Sheets as native Sheets from the start. And make deletion of the old version part of the same operation as creating the new one — not a follow-up step. Twice, "delete the old one" was deferred and never happened. Moving a file into a shared folder is irreversible Files moved into a folder shared to you transfer ownership to the other side. Moving in succeeds. Moving out fails: The caller does not have permission. Renaming fails too. Five files were moved to an accountant's folder prematurely. None could be retrieved. What to do: Check status before any move into a shared folder — anything pending means don't move it. When in doubt, don't. And accept that once it's done, it's done; don't burn cycles trying to reverse it. Patch files multiply until the system is unusable Every rule change created a new "update" document, because the main configuration file had grown too large to safely rewrite. Within two weeks: fifteen patch files. Contradictions between them. Two documents specifying different formats for the same task. Instructions no scheduled run would ever read, because they weren't in the file the run loads. What to do: Split configuration by topic into files small enough to rewrite whole — roughly 8-10KB each. Then add the rule that keeps it split: Never create a patch document to fix an existing rule. Edit the topic file itself. Without that rule, the split degrades back into a pile within a fortnight. It reports things you already handled Reports filled with items whose own description was "already reported this," "no action needed," "included for your awareness." Every one of those is noise. And noise trains you to skim reports — which is exactly when the one item that mattered slips past. What to do: One test before any item enters a report: What is the user supposed to do with this? "Nothing, it's handled" → it does not go in the report. And the part people resist: if nothing passes the test, there is no report. Finishing silently is a correct outcome. Keep full logs separately. Transparency lives in the log, not in the report. It re-opens decisions you already closed A decision made on Monday resurfaced Wednesday as a fresh suggestion — because the automated run saw the same state and reasoned its way to the same recommendation. What to do: Record decisions as decisions, with the date and the fact that they were made. Then: a question the user has already settled does not come back. And when you remove a mechanism, document that it was removed deliberately — otherwise a future run reconstructs it by analogy to the rules around it. That happened here too. It invents a mechanism instead of asking Told to record something "as expected income," with no format specified, the agent designed a full tracking apparatus: a zero-value row, a status, a register entry, a folder convention. It was reasonable. It was also entirely invented, and wrong for the case. What to do: Distinguish ambiguity from missing context. Missing format for something well-defined → ask, don't design. Genuine ambiguity in identity or amount → stop and ask. Merely lacking a reason for a clear transaction → record it and mark it pending. Three different situations; three different responses. Push notifications are not delivery confirmations The tool returns Mobile push requested. That means the request was issued. Nothing more. Tested twice under identical conditions with permissions confirmed working: once it arrived, once it didn't. Meanwhile the logs said "notification sent to user" — without checking the return value at all. What to do: Never write "notification sent" without reading the return value, and report it verbatim, including "skipped." For anything that matters, use a channel you can verify — email returns a message ID you can search for and confirm landed. The pattern underneath all seventeen Sort them and they collapse into three groups: The agent claimed it did something it didn't do. (#1, #2, #3, #4, #17) The agent concluded something from information it never had. (#5, #6, #7, #8) The agent's own structure worked against it. (#10, #11, #12, #13) Every one of them produced output that looked correct. None produced an error message. Most were found days later, by accident, while looking for something else. Which points at the real lesson, and it isn't a prompt: An agent that can act must be able to prove what it did — and must be built so that failure is loud. Silence is not success. It's usually just silence. What this is from These notes come from building an agent that runs a small company's bookkeeping: filing receipts, matching invoices to bank transactions, generating payment vouchers, tracking a live cash flow, and monitoring email for replies. It runs on scheduled tasks now, and it works. Getting there produced the seventeen failures above, plus a set of rules that prevent them. The rules are the part that transfers. Found this useful? The thing I'd most like to know is which of the seventeen you've hit. Some of these took days to diagnose because there was nothing to search for. That's the gap this is meant to close.
Key Takeaways
- •Field notes from two weeks of running an autonomous agent on real money Base64 uploads fail without an error Uploading a binary file (xlsx, zip, PDF) by having the model emit a base64 string fails above a certain size
- •This story was reported by Dev.to, covering developments in the dev space.
- •AI advancements continue to reshape industries — read the full article on Dev.to for complete coverage.
📖 Continue reading the full article:
Read Full Article on Dev.to →


