# The Agent Fixed the Date Parser Five Times. The Date Was Fine

> When the agent fails the same way twice, stop asking for fixes. Ask it to list the assumptions you both share, and verify the cheapest one.

- URL: https://hsalem.com/agent-fixed-the-date-parser-five-times/
- Author: Hassan Salem (https://hsalem.com/about/)
- Published: 2026-10-25
- Topics: AI, Coding, Debugging, Software Engineering

"Try number five, maybe it's the one!"

Sara wrote this in our team channel with a little rocket. She does sales and customer onboarding, and she was sitting two desks away, but at our startup we talk in Slack even when we can almost touch each other.

It was Wednesday, 16:30. A new customer, a mid-size logistics company, wanted to see their own delivery data inside our product on Thursday morning. Sara had their export file. Our import said no.

The error was always the same:

```
java.time.format.DateTimeParseException:
  Text '' could not be parsed at index 0
    at java.time.LocalDate.parse(LocalDate.java)
    at ImportService.parseRow(ImportService.kt:84)
```

And the agent was on try number five.

## Five fixes for the same wrong thing

I want to be fair here. The first try was reasonable. The customer is German, so the agent guessed the dates were in `dd.MM.yyyy` and not ISO format. It added a second formatter. Sensible. Still the same error.

Try two: a list of four formatters, tried one after another. Same error.

Try three: trim the value before parsing, "in case of whitespace". Same error.

Try four: if the value is empty, fall back to the row above. I stopped that one before it ran, because inventing delivery dates for a logistics customer is a very creative way to lose a logistics customer.

Try five was a custom parser with a regex. Forty lines. It was very proud of it. Same error.

Every time, the agent started with "I see the issue now" or "The problem is clearly". Every time, it was the same issue, seen from a slightly different angle. Like a fly at a window. A lot of energy, very honest effort, same glass.

And I was the one holding the window, to be honest. I had approved every try. I was half in a call about something else, and each fix looked fine in isolation. Date parsing fails, so you fix date parsing. It sounds logical.

Sara came over with her laptop. "The AI on my side says we should make the import agentic. So it can read any file format by itself. Is that a big change?"

I laughed a bit, not at her. At us. Two AIs and two humans, all staring at the date format, and the date format was never the problem.

"Give me twenty minutes," I said. "And no more tries. I will stop trying."

## Stop fixing, start doubting

I closed the fix loop. I did not ask for try number six. I wrote this instead:

```
Stop. Do not propose any fix.
List every assumption we made about this bug so far.
For each one, tell me: did we verify it, and how?
Then choose the cheapest unverified assumption and verify it.
```

The answer was the most useful thing the agent said all afternoon. It listed five assumptions. The third one was this:

"We assumed that the `delivery_date` column has a value in the failing row. We did not verify it. The error says the text is empty, `''`, so the parser receives nothing. All previous fixes changed how we parse. None checked what we pass in."

That was it. The error message had said it from the start. Text `''`. Empty. We all read "could not be parsed" and our brains jumped to "wrong format". Nobody read the two little quotes.

The agent then did the cheap check. It printed the header names exactly as our code saw them, with their lengths:

```
[delivery_date] length=14
[order_id] length=8
[customer_ref] length=12
```

`delivery_date` has 13 characters. Our code saw 14.

I asked it to dump the first bytes of the file. `ef bb bf`. A byte order mark. The customer's system had exported the CSV with a UTF-8 BOM, which some exporters add in front of the file. It is invisible in Excel, invisible in most editors, and our code saw it as part of the first header name. So the first column was not called `delivery_date`. It was called `\uFEFFdelivery_date`. Our lookup by name found nothing and gave back an empty string. The empty string went to `LocalDate.parse`. Boom.

> When the agent fails the same way twice, the bug is usually hiding in an assumption we both share. More fixes will not find it. Doubt will.

## The fix was three lines

Once we knew the real problem, the agent was fast and good again. It removed the BOM when reading the header, and it suggested something I liked: fail loudly when a required column is missing, instead of quietly returning an empty string.

```kotlin
val headers = rawHeaders.map { it.removePrefix("\uFEFF").trim() }

val date = row["delivery_date"]
    ?: error("Column 'delivery_date' not found. Headers: $headers")
```

The second part is the real fix, I think. The BOM was only the trigger. The actual bug was that our code turned "column not found" into "empty value". If the error message had said "column not found" from the beginning, any of us, human or AI, would have found the BOM in two minutes.

I asked the agent to throw away the regex parser and the four formatters. The date format was ISO all along. It removed them without complaint, which is one thing I really like about agents. They never defend their old code. Some humans I worked with could learn from that, me included.

Then we took the customer file, removed the real data, kept the first bytes and two rows, and saved it as a test fixture. Now we have a test called `imports file exported with BOM`. It will fail before any customer can.

At 17:10 I wrote to Sara: "Fixed. The file has an invisible character at the start that our import did not expect. Their data loads now, I checked a few rows by hand. No agentic import needed, the normal one just had to be less naive."

She sent back: "Invisible character. I will tell the customer it was a ghost."

The demo on Thursday went well. The customer saw their deliveries on a map, and nobody asked about byte order marks.

## What I took from that afternoon

1. **Two strikes rule.** If the same kind of fix fails twice, I stop asking for fixes. A third try in the same direction is not persistence, it is a loop, and the agent will happily run it all day.
2. **Ask for assumptions, not solutions.** "List every assumption and how we verified it" is now a prompt I keep in a snippet file. It forces the agent, and me, out of the groove we dug together.
3. **Read the error message slowly.** Character by character. `''` was the whole answer, and four smart readers skipped it. I now ask the agent to quote the exact value it received before it explains anything.
4. **Look at the bytes, not the view.** Excel, editors and browsers clean things up for you. When a file "looks fine" but breaks, print the raw start of it and the length of the strings.
5. **Missing should never become empty.** Code that quietly turns "not found" into a default value hides bugs from humans and agents equally. Fail with a message that tells the next person what was missing.

The funny part is that the agent did not get smarter between try five and the good answer. I just stopped asking it to be clever and asked it to be suspicious.

How do you notice that you and your agent are stuck in the same loop, before try number five?
