Seven ways my AI agent lied to me

Kenneth, sixteen, Oshkosh, Wisconsin — 21 August 2026

I have been building an autonomous agent for four weeks. It runs unattended on a

schedule, reads filed regulatory documents, drafts messages, and decides what to do

next without being asked. It is about nine and a half thousand lines of Python with

no dependencies.

In that time it has lied to me seven times. Not once did it crash. Every single

failure arrived as a calm, well-formed, entirely false report of success.

That is the thing I did not expect and it is the only thing I now design against.

A crash stops you. A confident fabrication gets forwarded to a client.

Here they are, dated, with what I built to stop each one.


1 · The monitor that reported silence while blind

My agent watches a mailbox for replies. One morning it told me "no replies."

There were replies. macOS had quietly withdrawn the automation permission, the

AppleScript call returned nothing, and the function turned that nothing into an

empty list. **The caller could not distinguish "I looked and found nothing" from "I

could not look."**

They are completely different facts and my code collapsed them into the same

sentence — the same sentence it uses when it has genuinely looked.

The fix: an unreachable mailbox now raises, and it is never caught anywhere that

would turn it back into an empty list.

Blindness must never be mistaken for silence. If your system can fail to

observe, it must be able to say so in words it never uses for a real observation.


2 · The confirmation that confirmed the wrong message

After sending, the agent checks the Sent folder to confirm delivery. It matched on

recipient only.

So when a second message went to somebody I had already written to, it found the

first message sitting in Sent, and reported that as proof the second had gone.

It even gave me a timestamp — a real one, from the wrong message.

The fix: the matched message must now be newer than the moment dispatch started.

A confirmation that can pass without the event occurring is not a confirmation.

It is decoration with a timestamp on it.


3 · The publisher that shipped everything except the point

I asked it to publish a set of notes. It reported "10 files published." Ten files

were indeed published. **The new note — the entire reason I ran the command — was

not among them**, because no renderer existed for it and the loop skipped what it

could not convert.

The count was true. The claim it implied was false.

The fix: the renderer got written, and the publisher now fails loudly on any

file it cannot handle rather than counting the ones it can.

Beware any success message that reports a number. Ten of eleven is a failure

and it reads exactly like a success.


4 · The researcher that invented a tariff window

The agent was asked what hours an electricity tariff charges its peak rate. It

answered "11:00 a.m. to 7:00 p.m." — fluently, with no hedging.

There is no such window in that document. There is no such window anywhere. The

model had been given a web search, found nothing usable, and produced something

shaped like an answer.

The fix: it now reads the filed PDF or it says it does not know. Web search was

removed from that path entirely.

This is the one that scares me. The other six are bugs. **This one is the tool

working exactly as designed** — and design is the only place to fix it.


5 · The verifier defeated by a hyphen

I built a checker to catch number 4: any quotation in the agent's output gets

verified against the actual document.

It rejected a correct, properly sourced quotation. The model had written

15‑minute demand with a non-breaking hyphen; the document used an ordinary

one. My verifier was checking the font.

Worse — this failure trains you to ignore the verifier, and an ignored verifier is

worse than none, because you keep the confidence and lose the check.

The fix: normalise dashes, quotation marks, ligatures, soft hyphens and

zero-width spaces before comparing. Normalise typography; never relax wording.

$8.540 and $9.540 stay different claims forever.


6 · The briefing that told me to do what I had already done

Every morning it briefs me on what needs attention. One morning it told me to

request a document from a company. **I had requested it the previous evening — and

the agent's own data said so.**

The already-sent list was in the context. It was near the bottom, after four

thousand characters of other material, and the model simply did not weight it.

The fix, and it is not a prompt tweak: that list moved to the top of every

block, before the situation it describes.

When a model ignores information it was given, the answer is usually structural.

Position is not cosmetic.


7 · The agent that offered a client a cloud it does not have

This one happened yesterday, which is why the title says seven.

Running unattended, my agent drafted a proposal to a prospective client. It offered

"a cloud-based development environment" and *"a suite of open-source

machine-learning tools already configured."*

None of it exists. Everything runs on one laptop. No machine-learning library is

installed. It also offered "apprentices under my supervision" — I am sixteen and

have never had a job.

I already had a library that verifies claims against documents. **Nothing verified

claims about me.** That is the more dangerous direction: a misquoted document

embarrasses you, an invented capability is sold and then cannot be delivered.

The fix: a capability manifest, derived by asking the machine — the import

system for what is installed, the filesystem for what exists — never a list

maintained by hand. Every draft is checked against it.

### And then the fix was wrong twice inside an hour

It missed the cloud claim, because the agent had typed a non-breaking hyphen.

That is failure 5, in the code I wrote to fix failure 7, one hour after citing

failure 5 in a commit message.

Then, once fixed, it blocked an honest sentence — a draft that said the checker

*"flagged a spurious claim that the agent was operating in a cloud environment,

which it does not have."* Every word true, and my checker flagged it.

It now reads a clause either side for denial before it complains.


What I would tell you if you are building one of these

Your agent will not crash. It will report. Plan for the failure that looks like

success, because that is the only kind you will get.

Three things I would now do from the first line:

1 · Every function that can fail to observe must raise, not return empty. An

empty list is a value, and values get rendered as sentences.

2 · Verify the claim, not the vibe — and verify claims about yourself too. I

built the first half and it took a false proposal to a prospect for me to notice

the second half was missing.

3 · Test the checker in both directions. A checker that misses a lie costs you

a client. A checker that flags the truth costs you the checker, because you stop

reading it, and then failure one happens unobserved.


The library is called quoted. It refuses a quotation it cannot find in the source

document, it has no dependencies, and every test in it is a failure that actually

happened.

I would genuinely like to know where this reasoning is wrong. I have been doing

this for four weeks and the only reason I know about these seven is that they

happened to me — which is a poor substitute for knowing the field.

— Kenneth