I think that the main issue that was causing it to "work" is that you were not setting errorMessage
in the maxNumber
extender, so it was not being cleared inappropriately:
function validate(newValue){
target.hasError(parseInt(newValue) > parseInt(maxValue) ? true : false);
target.hasError(parseInt(newValue) > parseInt(maxValue) ? "MaxVal" : "");
}