Error 415: why a record couldn’t be deleted
The librarian created a record from an ISBN, tried to delete it — and got “HTTP 415: JSON expected”. How a security rule broke deletion, and why you fix the rule rather than add an exception.
In this section we are candid about failures. Not because there are many, but because bugs show best how a system is built.

What the librarian saw
The record “Flucht – Vertreibung – Neuanfang” had been created with the new ISBN lookup. Everything came through correctly. Then came deletion with double confirmation: the first dialog, a “Continue to confirmation” button, and a red line at the bottom: HTTP 415: JSON expected.
What actually happened
Shortly before, the server had received extra protection. One of the rules sounded reasonable: every request that changes something must arrive in JSON format. That closes a whole class of attacks in which another site tries to submit a form on behalf of a logged-in user.
But some actions carry no data at all. Deleting a record sends only “delete record no. …” — with no request body. For such cases the rule had a list of exceptions: logout, deleting a user, uploading a logo. Record deletion wasn’t on the list.
Why not just add an exception
The quickest fix would be to add record deletion to the list. But that treats the symptom. The same body-less requests exist for restoring from the trash, permanent deletion, “Release hold”, “Return to shelf”. Every new action would become a new trap.
The right fix is to change the rule itself: require JSON only when a request actually carries data. That doesn’t weaken protection: body-less requests are still checked by origin and by a security token that only an open tab of the site itself knows.
What we asked for
- Change the rule in general termsJSON is required only if the request has a body. The exception list is no longer needed.
- Go through every state-changing actionDeletion, trash, requests, renewals, passwords, import, fields — an automated test for each.
- Check by handCreate a test record, delete it, find it in the trash, restore it, delete it again.
The lesson
Security rules must also be tested against real user actions, not only against attacks. The bug wasn’t found by a test but by a librarian simply working with the system. That is why in Katlog we test with live scenarios: create, delete, restore.
Epilogue
After the fix, the very same record “Flucht – Vertreibung – Neuanfang” was deleted without a single error and now sits in the trash, where it can be restored for 30 days. A check on the live site closed the story that had started there.