The Feature Worked Exactly as Specified and Was Unusable
Our CSV import had a 750-row limit, and uploading a second file replaced the first. Every part behaved as designed. A client with 3,000 records still had no way to get them in.
Our bulk import accepted a CSV of up to 750 rows. The limit was deliberate. It kept request sizes sane and processing predictable. It was written down, it was tested, it worked.
Then a client wrote in. They had a few thousand records. They'd uploaded the first 750, then uploaded the next file, and the second upload had replaced the first instead of adding to it.
Nothing failed. No error, no bug, nothing in the logs. Every component did precisely what it was designed to do, and the user's actual job, get my data into your system, was impossible.
Works, and usable
The 750-row cap made sense on its own. So did replace-on-upload: if you're correcting a file you just sent, replacing it is the sane behaviour.
Together you get a feature with a hard ceiling and no way over it. Each decision locally reasonable, the combination unusable. That's the most common way features end up broken. Nobody chose it. It emerged from two people making sensible calls about different parts.
Which is why I've stopped trusting "does the feature work?" The useful question is whether the person can complete the job they came here to do. Those come apart more often than you'd expect, and only the second one is what the client is paying for.
Real customer data isn't shaped like your fixtures
The other half of this work had nothing to do with limits.
Universities export from their own student systems, which carry their own history and their own accumulated mess. A file arrives referencing a programme renamed two years ago, or a department that no longer exists, or a field left blank because whoever maintains that spreadsheet knows it doesn't matter.
The strict response is to reject the file and list the errors. Defensible. For a 3,000-row file it means the client fixes a reference, re-uploads, hits the next problem on row 1,400, fixes that, re-uploads. Every cycle costs them an hour and costs you a support conversation.
So where it's safe, we import what's valid and drop what can't be resolved rather than refusing everything. The row lands, the unresolvable reference doesn't, and the client isn't blocked on a data cleanup project they never signed up for. Where dropping data quietly isn't safe, it still fails loudly. The point isn't to be permissive everywhere. It's to decide deliberately instead of defaulting to strict because strict is easier to implement.
What I'd do differently
Test with the biggest file a real client would send, not the biggest file that's convenient. The 750-row limit was fine against a 200-row fixture and fine in every demo. It broke against a real client's real export, which is exactly when you don't want to find out.
Treat "what happens on the second upload?" as a required question. Every import feature has a second-upload behaviour whether or not anyone decided on it. If nobody decided, you shipped one anyway, and it's whatever fell out of the implementation.
And ask what the ceiling means for the largest customer you want. A limit isn't only a technical constraint, it's a statement about who can use the product. A cap that quietly excludes your biggest prospective clients is a commercial decision being made by accident, in a config value, by someone who wasn't thinking about sales.
How it landed
The multi-batch fix went in and was later pulled back off the main branch as part of a coordinated release cut, alongside other changes not going into that deployment. Normal release management, and worth saying plainly rather than implying a clean ending. The diagnosis and the fix were right. The path from "fix written" to "fix in front of the client" ran through a process with its own timing.
The part I'd keep either way is the diagnosis. A client told us the feature didn't work. Every metric we had said it did. They were right and our metrics were measuring the wrong thing, which is the recurring theme of nearly everything I find worth writing down.