In Mexico, most people have two surnames: one from each parent. María Fernanda López Hernández is one person with one full name.
Now give her a form built somewhere else. "First name." "Last name." One field each, 20 characters max, letters only. She types "López Hernández," the accent breaks validation, the space gets trimmed, and somewhere downstream a bank, an airline or a government system now thinks she's a different person from the one on her ID.
Nobody meant to exclude her. Someone just wrote a schema.
Classifying is never just grouping
In 1903, Émile Durkheim and Marcel Mauss published a short study called Primitive Classification. Their argument was simple and uncomfortable: when people classify things, they don't just sort them into boxes. They arrange the boxes into a hierarchy. Some categories become central, others marginal. And that order doesn't come from nature; it comes from society.
Decades later, Mary Douglas took the idea further in Purity and Danger (1966). Every classification system produces leftovers: things that don't fit. She famously described dirt as "matter out of place." The anomaly isn't wrong in itself; it's wrong according to the system.
Now look at a form validation error. A red border, a message that says "Invalid name." The person is the anomaly. The system is the norm.
As engineers, we write classification systems all day. We just call them enum, required, maxLength and regex.
Five places we classify people without noticing
1. Names
The classic. Patrick McKenzie's 2010 post "Falsehoods Programmers Believe About Names" is still the best list, and still mostly ignored.
// Before: a Western, ASCII-only idea of a name
const nameSchema = z.object({
firstName: z.string().regex(/^[A-Za-z]+$/).max(20),
lastName: z.string().regex(/^[A-Za-z]+$/).max(20),
});
This rejects accents, ñ, apostrophes (O'Brien), hyphens, spaces, two surnames, non-Latin scripts and people with a single name.
// After: ask for what you need, accept what people are
const nameSchema = z.object({
fullName: z.string().trim().min(1).max(200),
preferredName: z.string().trim().max(100).optional(), // "What should we call you?"
});
If a legal process truly needs separate fields (KYC, travel), label them for the people you serve ("Apellido paterno," "Apellido materno") and make the second one optional.
2. Gender
<!-- Before -->
<select name="gender" required>
<option>Male</option>
<option>Female</option>
</select>
First question: do you need it at all? Most products don't. If you do, explain why, make it optional, and offer more than two options plus "Prefer not to say." If what you actually need is how to address someone, ask for pronouns or a title instead.
3. Addresses and phone numbers
"State" as a required dropdown of US states. A ZIP code regex with exactly five digits. A phone field that rejects the +52 prefix or spaces. Each one tells part of the world it isn't your user.
Use a free-text address line, a country selector that drives the rest of the form, and a library like libphonenumber instead of a homemade regex.
4. Enums for life
type MaritalStatus = 'single' | 'married' | 'divorced' | 'widowed';
That union type is a theory of which families exist. It leaves out common-law unions, which are widespread in Latin America, among others. If the business doesn't depend on the answer, don't ask. If it does, check the categories against the legal reality of each market you serve, not against the one you know.
5. Validation as a gatekeeper
Every validation rule is a small border. Some are necessary: an email needs an @. Many are just habits: minimum name length of 2 (there are people named "O" and "Ng"), no numbers in names, a birth date that must make you under 100.
A good question for code review: who does this rule reject, and is that on purpose?
What it costs
In payments and fintech, these aren't edge cases. A name that doesn't match an ID can fail identity verification. A rejected address blocks a delivery. People learn to lie to get through a form, and your data gets dirtier than if you had just accepted the truth.
And beyond the metrics, people notice. Being told by a computer that your own name is invalid is a small, repeated humiliation. Users rarely file a bug for it. They just leave.
A checklist for more humane data models
- Ask only for what you need, and be able to say why for each field.
- Prefer free text over enums when you're not sure the categories are complete.
- Validate the minimum that the system truly requires.
- Design for the countries you actually serve, starting with your own.
- Test with real names: two surnames, accents, apostrophes, single names, non-Latin scripts.
- Look at your "Other" bucket. Whoever lands there is who your classification forgot.
- Let people correct their data without calling support.
Your schema is a theory of who counts
Durkheim and Mauss studied totems and clans. We write TypeScript. But the mechanism is the same: we draw categories, rank them, and treat whatever doesn't fit as an error.
A data model is a theory about who is a normal user of your product. You're going to write one either way. Better to write it on purpose.
This piece comes from my background in social anthropology and an essay I wrote during my master's on the body, culture and classification. It's part of my series on the human side of interfaces.
What's the strangest field validation that ever rejected you? Share it in the comments.
References
- Durkheim, Émile, and Marcel Mauss. Primitive Classification. 1903.
- Douglas, Mary. Purity and Danger. Routledge, 1966.
- McKenzie, Patrick. "Falsehoods Programmers Believe About Names." 2010.
- W3C Internationalization. "Personal names around the world."
Top comments (0)