I couldn't find any mention of this decision on esdiscuss, so I can only offer my own perspective.
As a commentor points out, this is part of larger trend in ES 2015 to allow non-object inputs more broadly. In the ES 2015 spec, the phrase, "In the previous edition, a non-object argument always causes a TypeError to be thrown," appears in reference to 10 different methods on Object.
For one, this change brings the behavior of Object.keys into congruity with the behavior of for-in loops, which have always been able to operate on primitives. Considering that the specification already required order to match between Object.keys and for-in, requiring the same set of valid operands seems unsurprising.
This change seems nearly as harmless as can be to existing code while greatly reducing the brittleness of Object.keys. Even in your case of a try-catch, it's difficult to imagine a case where successful Object.keys execution causes an actual problem. I can easily imagine code like this:
try {
var keys = Object.keys(input);
} catch {
// oops, input was a primitive; call `new [Constructor]` to wrap it
var keys = Object.keys(
new input.constructor(input)
);
}
But this doesn't break when Object.keys doesn't error out; a successful Object.keys call makes the catch code obsolete.
Of course there might exist, somewhere, code like this:
try {
var keys = Object.keys(input);
} catch {
// oops, input was a primitive; that unlocks the secret prize
giveUserAFreePuppy();
}
Basically, what I'm trying to say, through a very silly example, is that the cases where skipping a catch block would be truly problematic for the operation of some code seem so far-fetched that breaking such code seems a small price to pay to get a less brittle Object.keys function.