Often, it's because people make them so. Often, it's because people recycle broken solutions instead of really thinking about what they're trying to do. Most code out there solves trivial problems, but is insanely complex. Web frameworks are especially bad at that.
"Deliveries are not made on Tuesdays, unless it falls on the 9th day of the month, but not in June for tax purposes in 2013, 2014 and 1998. Our Nowheresville office is excluded from the above rule."
You get rules like this. And there's reasons for most of them. Sometimes very good reasons.
Often, what simplifies a business process on the surface actually doubles (or worse) the underlying code. Because managers don't want you to throw away old data because it doesn't fit the new schema.
The "happy path" is always simple. And it tends to wind up being a fraction of the actual, evolved production code.
Unless you work in large organisations with long-lived systems, this will never be part of your worldview.
Sure, there are complexities like that in the world. However, where programmer A writes an if-else statement or, maybe, a 5-line dynamic dispatch, programmer B installs some "enterprise" framework or a rules engine, instantly making the entire system an order of magnitude more complex.
What programmers like B often doesn't realize is that they push core logic of the application from their source code (Turing complete, expressive, versioned, benefiting from static and dynamic analysis and all the testing/refactoring tools available for the language) into an obscure XML notation or even some proprietary rules database, worked upon by a complicated blob of 3d party code that has nothing to do with the original business problem.
Well we're talking about different things, now. Per Brooks, I was talking about essential complexity, you're talking about accidental complexity.
The point is that in web frameworks, the two are often confused or at least blurry. So we need to extend the essential/accidental dichotomy to deal with global versus local views.
Take for example parsing emails. In a universal sense the complexity is accidental, it arose from the technology decisions of the authors of RFC822 (which partly arose from previous decisions).
But locally, for a web programmer, the email address format is an immutable, irreducible fact of reality. I can no more wish away that complexity than I can wish myself a million dollars. To me it is an essential complexity.
Where web frameworks of the entirely-made-out-of-code variety really shine is in facing up to these locally essential complexities. It may seem superfluous now. It may not seem so in six months.
Often, it's because people make them so. Often, it's because people recycle broken solutions instead of really thinking about what they're trying to do. Most code out there solves trivial problems, but is insanely complex. Web frameworks are especially bad at that.