A `Rectangle` builder validates each dimension in its own setter — `width(int w) { if (w <= 0) throw ...; this.w = w; return this; }` — and the object still ends up with an invalid combination in production: width and height set fine individually, but the resulting rectangle violates a rule that only makes sense once both are known ("an expedited shipment needs an address", in the lesson's own example). What's the actual rule for where builder validation belongs, and why does per-setter validation miss this?
Validating in each setter can only ever check that one field, in isolation, looks reasonable — it has no way to see the combination of fields, because at the moment any single setter runs, the others may not have been called yet. The rule the lesson states directly is: validate in build(), not in the setters, because build() is the only point where the object is actually complete and every field the invariant depends on is known. A rule like "expedited orders need an address" — or, in this question, any rule that relates width to height, or one field's presence to another's — simply cannot be checked correctly anywhere earlier, because earlier there is no guarantee the second field has been set at all. A builder that validates only in setters and does nothing in build() is, in the lesson's own words, a mutable object with extra steps: each individual assignment looks safe, and the object as a whole can still be built into a state nothing ever checked.