Conclusion: design for humans and default to non-fatal situations.
It's a lot safer to fail fast and fail safe than to hobble along with possibly undefined state doing who knows what to the system and to the user's data.
You're missing my point. It's not about undefined state -- it's about sane defaults and APIs that make things that crashes/bad things harder to achieve. Kill's -1 is an example of this -- having a separate killall api is defaulting to a non-fatal situation. Apple's UITableView's is another -- it's so easy for them to rebuild themselves yet instead it crashes on an inconsistency.
If a developer fails to check the return value of a function that can fail, all bets are off. There is no sane default that can safely hide a developer mistake.
Granted, the specific kill() API could have been designed better, but since it's very well established by decades of history, the burden of understanding it lies with the developer.
Because nothing ever changes with computers over time? You're being myopic. It's not about fork->kill. It's about how computers work in general, and why this 'blame the programmer' mindset is just dumb.
As you admitted, the API could have been designed better. That's my point. Things that break things for users, especially those that take down entire systems, should be difficult or require more awareness to do, such as by naming it killall() like suggested in this thread. The human factors approach recognizes that operators aka programmers aka humans will not just make errors, but predictability so. We can incorporate those predictions into our domain and change design patterns to match.
There are many known patterns of errors that programmers make: edge case errors such as off-by-one, null dereferencing, etc.
Using the return value from a function is a common pattern generally. Having a return value that mixes an actual result (PID) along with an error code (-1) is problematic in that they're both integers so there's no obvious handler for the error case, and thus this cascade can happen. Then you add the fact that fork() rarely fails and that compounds the issue in hiding it into obscurity.
Generally when a system is maxed out of resources all kinds of things break and fail in weird ways; it just so happened that this particular cascade was super bad and needlessly so because of API design choices that have never been addressed.
It's a lot safer to fail fast and fail safe than to hobble along with possibly undefined state doing who knows what to the system and to the user's data.