Design for the Weird Stuff

Most software is designed around a clean version of reality. A user enters the right information. A file arrives in the expected format. Two records that belong together match perfectly. An
outside system responds when it is supposed to. Nobody clicks the wrong thing, nothing
changes unexpectedly, and the process moves neatly from start to finish.
Then the software meets real life.
A person changes their name. An identifier is different from the one that appeared last month. A
file contains a thousand records and three of them are missing something important. Two
systems disagree about the same piece of information. A response never comes back.
Someone submits the same thing twice. The data is technically valid, but something about it
clearly does not make sense.
That is the weird stuff, and in a lot of systems, that is where the real design work begins.
The happy path matters, of course. A form should save when someone fills it out correctly. A
valid file should process. A record that clearly matches another record should connect without
unnecessary friction. But those scenarios are usually the easiest ones to define. The harder part
is deciding what should happen when the answer is not obvious.
What happens when 997 records process successfully and three do not? Should the entire file
fail? Should the three bad records disappear into a log somewhere? Should the system stop
and wait for a person? What if two records look like they belong to the same person, but one
important detail is different? What if an outside platform confirms receipt of something but never
sends the next response the system expected?
Those questions can feel like edge cases during planning, but they often become a major part
of the actual workflow. Real-world data changes constantly. People move, change names,
switch plans, update contact information, or appear differently across systems. Organizations
change rules. External vendors change formats. Legacy data carries years of inconsistencies
forward. Even perfectly reasonable users will eventually interact with software in a way nobody
predicted during design.
At some point, enough edge cases stop being edge cases. They are simply the environment the
software has to survive in.
That is why one of the most useful questions a product team can ask early is,
“What if?” What if
this is missing? What if we have already seen it? What if it matches almost perfectly, but not
quite? What if the external system is unavailable? What if the value is technically allowed but
wildly different from what we usually see? What if processing stops halfway through?Those questions are not signs of overthinking. They are how resilient systems get designed.
One of the most common places this shows up is in the way software thinks about success and
failure. Systems tend to prefer clean, binary answers: valid or invalid, matched or unmatched,
success or failure. Reality is often somewhere in the middle.
A process can be mostly successful. A record can probably match without being certain. A
response can confirm one part of a transaction without confirming the entire process. A file can
be structurally correct while containing one record that needs attention.
Good software has room for those states.
Instead of treating every irregularity as a complete failure, the system can separate what worked
from what needs review. It can process the valid records, preserve the exceptions, explain why
those exceptions were created, and give someone a clear path for resolving them. That is a
much more useful outcome than forcing an entire process to stop because one small piece did
not fit perfectly.
It also means recognizing that automation should not always make the final decision. Software
is excellent at applying clear rules. If a required value is missing, the answer may be
straightforward. If a number is outside an allowed range, the system can flag it. If two unique
identifiers match exactly, the system may have enough confidence to act automatically.
Other situations require judgment.
Two records may have the same date of birth and address but slightly different names. An
identifier may have changed while everything else remains consistent. Most of the data may
point in one direction while one field points somewhere else. In those moments, forcing the
system to choose can create more problems than asking for help.
Sometimes the smartest response software can give is,
“I am not sure.
”
That is where manual review becomes valuable. Manual review is sometimes treated as
something that should eventually be engineered away, but in a well-designed system, it can be
an intentional safety mechanism. The goal is not necessarily to automate every decision. The
goal is to automate the decisions that are safe and predictable, then make the uncertain ones
as easy as possible for a person to resolve.
The quality of that experience matters too. If software routes something for review, the person
should not have to reconstruct the entire situation from scratch. The system should explain what
triggered the exception, show the information that matters, highlight what changed, and make
the next decision clear. A manual review queue should not be a dumping ground for everything
the software could not figure out. It should be a decision-support tool.The same idea applies to failures. An error message that says “Processing failed” is technically
a message, but it is not much of an explanation. Useful software should tell people what
happened, what was affected, and what they can do next.
There is a big difference between telling someone,
“Import failed,
” and telling them that 996
records were processed successfully, four require review, and here are the reasons why.
Designing for the weird stuff also means accepting that some problems will not be discovered
until the software is used in the real world. No amount of planning will predict every variation in
data, every unexpected sequence of events, or every creative thing a user will eventually try.
That does not mean the design failed. It means the system needs to be built in a way that can
learn.
Good systems leave evidence behind. They record what happened. They preserve the original
input. They make unusual events visible. They help teams understand why something behaved
differently than expected. That visibility makes it possible to improve the rules over time instead
of repeatedly solving the same mystery.
In that sense, designing for the weird stuff is not really about predicting every weird thing.
It is about building software that responds well when the unexpected eventually happens.
The happy path shows that a feature works.
The weird stuff shows whether the system was actually designed.
And in our experience, that is usually where the craft is.
Gnomon Technology
The craft behind your code.
Contact Us
Start Your Project With Us
Take the first step toward building your custom software solution. Share your vision with us, and let’s discuss how we can bring your ideas to life. We're ready to help you start your project today!
