Menu · Back office

A default that never applied, and the dish that would not save

Adding a new dish failed with a NOT NULL constraint error printed on screen. The column had a default. Defaults do not work the way most people assume, and a second bug report turned out to be the same one from the other end.


Somebody added a dish, pressed Save, and got this:

D1_ERROR: NOT NULL constraint failed: recipes.menu_category

No dish was created. The message names a database column at a person who was trying to add a burrito.

The part that surprises people

The column in question is set up exactly as you would want: it must have a value, and if you do not give one it defaults to empty. Reading that, you would expect a save with no menu section to quietly land as empty.

It does not, and this is the bit worth knowing. A column default only applies when the insert leaves the column out entirely. If the insert mentions the column and hands it nothing — a genuine, explicit nothing — the default never gets a chance. The rule fires, the save is refused.

Our code sent "no section" as an explicit nothing. Every dish created with a section worked. Every dish created without one failed. Whether it worked depended on a field most people leave blank.

The second bug report was the same bug

The same tester had filed a separate finding earlier: create a recipe, and the count goes up but the list still says there is nothing in this tab. Two reports, different screens, filed days apart.

They were one thing. The create was failing, so nothing arrived to show. The list was not hiding a dish — there was no dish. Fixing the save fixed both, and we only noticed they were connected because we reproduced the first one properly instead of reading the screen and guessing.

What an operator can take from this

Two things, and neither requires knowing what a constraint is.

If a save fails, try it again with every optional field filled in. If it then works, the problem is a field you left blank, and that is worth saying in the support message — it is the single most useful sentence you can send.

A database error on a screen is a bug in its own right, apart from whatever caused it. It tells the person nothing they can act on, and it tells anyone standing behind them more about your system than they should see.


Try it on tonight’s service.

Nothing to install, no card. Not better by the weekend? Close the tab.