Coding with AI is making me less tolerant of ambiguity
Published

One thing I’ve noticed while coding with AI: a small ambiguity in the code can turn into a much bigger discussion than I expected.
A nullable attribute is a good example. I see a field that can be null, and I may already know why. The assistant still has to work it out. Is the value missing? Is that a valid state? Should it use a default, skip something, or report an error?
I’ve noticed it taking the cautious approach in situations like this. It asks more questions and adds checks. The result can look reasonable and still miss what I wanted.
Take a simplified example:
type Offer = {
discountPercent: number | null;
};
What should the application display when the discount is null?
If it means there is no discount, showing the regular price makes sense. If it means eligibility has not been checked yet, showing the regular price could be premature.
The type allows null, but doesn’t explain what it means.
It would be easy to write:
const discount = offer.discountPercent ?? 0;
That converts null to zero. It also makes a product decision: missing means no discount.
If that is the intended behavior, fine. Otherwise, the fallback treats an unresolved discount as no discount.
If a value is required, I want the type to require it. But replacing null with 0 or an empty string doesn’t help if I haven’t decided what the absence means.
When the states need different behavior, I would rather name them:
type Discount =
| { status: "pending" }
| { status: "none" }
| { status: "available"; percent: number };
The type distinguishes a pending decision from no discount. I still need to decide what to display while eligibility is pending, but the caller can tell those situations apart.
I wouldn’t introduce those states if the distinction didn’t matter. A nullable field with one clear meaning can be perfectly adequate. The thing I want to avoid is having several meanings hidden behind the same value.
The same question applies beyond nullable attributes.
Consider an update request. Leaving out a field might mean “keep the current value.” Sending null might mean “clear it.” If I ask an assistant to treat both as missing, I can erase a distinction the API needs.
These are ordinary software design questions. Working with AI gives me another reason to answer them explicitly. I can’t assume the context in my head will be available when the assistant reaches that part of the code.
I also don’t want to solve this by putting a paragraph of instructions around every field. If the type can express the rule, I’d prefer that. If an example can explain the behavior, I’d put it in a test. If there’s a reason for an unusual choice, that’s useful context to write down.
And sometimes the question really is unanswered. In that case, asking me is useful. I’d rather make the decision than review code built on an assumption I never agreed to.
For now, nullable attributes are one thing I’m paying more attention to. Before leaving a field nullable, I want to be able to answer two questions: what does absence mean here, and what should the caller do about it?