Three bugs I shipped into a 3D print
None were visible in the CAD viewport. All three were caught the same way — by checking the output instead of trusting the input.

I designed a wall-mounted letter rail recently — a 12-inch ledge with a raked slot that holds loose printed letters at a fixed angle. Simple object. Three real bugs made it into the model before anything reached a printer.
None of them were visible in the CAD viewport. All three were caught the same way: by checking the output instead of trusting the input.
The first was a mesh that was not actually solid. The rail has three countersunk screw holes, and after cutting them the model looked perfect. It was not printable. I read the exported STL back and checked that every edge had exactly two faces — three edges did not, one per screw.
The cause was subtle. I had angled each hole to sit square to the raked back face, which is the right call for seating a screw head flush. But that put the countersink's rim circle in exactly the same plane as the face it was cutting. Two surfaces occupying the same plane is a coin-flip for any boolean operation, and it left the mesh non-manifold — the digital equivalent of a hole in a bucket. The fix was to run the cone a fraction past the face instead of stopping on it. The opening is unchanged; the tie is broken.
The lesson: exporting is not verifying. Read the file back and assert something about it.
The second bug I found by rendering a close-up and looking at it. There was a thin crescent of missing material in the slot floor, right where letters sit. My first theory was wrong — I rewrote a completely different part of the model, changed nothing, and had to start over.
So I stopped guessing and dumped the actual cross-section through the screw. The coordinates said the countersink was reaching a full millimetre below the slot floor and scooping a bite out of it. The cone keeps widening as it travels, and I had told it to run a fixed distance past the face — by the time it got there it had grown enough to break through the floor beneath. It now stops relative to the face it is cutting rather than a fixed distance.
The lesson: when a fix changes nothing, stop fixing and start measuring. I burned a rewrite on a confident wrong theory. The numbers took two minutes and were unambiguous.
The third was not in the print at all. It was in a text filter I built the same day, which pulls news headlines and screens out anything grim. I wrote a keyword blocklist and tested it against 192 real headlines. It was matching "war" inside "award" and "warehouse", and "dead" inside "deadline". Meanwhile it sailed straight past "record debt" and "stock sinks", because a blocklist catches explicit horror and nothing else.
The lesson: test against real data, not imagined data. Every one of those collisions was obvious the moment actual headlines went through it, and invisible while I was reasoning about it in my head.
Three different domains — mesh geometry, boolean operations, text matching. One pattern: the bug was never where the design was. It was in the gap between what I intended and what the output actually contained.
This is the same discipline we bring to automation work. When we build a system that answers your phone or files your orders, the question is never whether the flow chart looks right. It is what the system actually did, on real inputs, when nobody was watching. That is why every system we ship logs its work and reports back to you — not because it is a nice feature, but because a system you cannot inspect is one you are trusting on faith.
Next lesson
How 3D printing actually works
The plain-English version of FDM printing, layer by layer.
Read next