One of the main pushbacks in this article is on the difficulty of later edits once the domain changes. The "make invalid states unrepresentable" mantra really came out of the strongly typed functional programming crowd – Elm, F#, Haskell, and now adopted by Rust. These all have exceptionally strong compilers, a main advantage of which is _easier refactoring_.

Which side of the argument one falls on is likely to be heavily influenced by which language they're writing. The mantra is likely worth sticking to heavily in, say, Haskell or Rust, and I've had plenty of success with it in Swift. Go or Java on the other hand? You'd probably want to err on the side of flexibility because that suits the language more and you can rely on the compiler less during development.

Perhaps it's not really language but the type of programs developers use these languages for? Open vs closed systems, heavy/light interactions with the outside world, how long they're maintained, how much they change, etc.

I can tell you the language is a huge part of it. I used to code in ObjC and now I’m using Swift; refactoring is easy in Swift and was a pain in ObjC.

I know I can trust my Swift code. Usually when it compiles it works because I try to, and often can, make invalid states unrepresentable. My ObjC code was always full of holes because doing so was not so easy (or not possible at all)…

The gist of that advice is that closed systems are that much easier to work with.

The tradeoff open system users have to evaluate is whether they’d rather have data rejected and not evaluated if it doesn’t fit their model of it (extreme case: your program silently drops key instructions), or whether they’d rather have their program work with data it wasn’t built to understand (extreme case: sql injections).

Proponents of this mantra argue that it’s easier to make a process to monitor rejected inputs than to fix issues created by rogue data.

That might be another factor. You could say that a program in a stable ecosystem doesn't need changing so should priorities strictness over flexibility. However even in a changing ecosystem, rather than building in flexibility that allows for incorrect states, you can raise the level of abstraction and build in extension points that still retain nearly the same strictness while still giving you the flexibility to change in the future in the ways that you will need.

easier refactoring - for the cost of having much more of it

flexibility saves the effort and allows doing more of the Actual Things

The Actual Things being mostly fixing technical debt introduced over the years by not making invalid states unrepresentable

This is what I’ve found as well. The actual things are fixing a lot more bugs or reimplementing the state checks all over the place.