             # the amount displayed remaining subtracts off the amount you type in
             show_remaining = misc.round2(remaining + current - current_input)
 
-            val = @state["upgrade_#{name}"]
-            if misc.parse_number_input(val)?
+            val = misc.parse_number_input(@state["upgrade_#{name}"])
+            if val?
                 if not @is_upgrade_input_valid(Math.max(val, 0), limit)
                     reasons = []
                     if val > remaining + current then reasons.push('not enough upgrades')
-                    if val > limit then reasons.push('exceeding limit')
+                    if val > proj_remainder + current then reasons.push('exceeding limit')
                     reason = reasons.join(' and ')
                     bs_style = 'error'
                     label = <div style={UPGRADE_ERROR_STYLE}>Value too high: {reason}</div>


        else if input_type == 'number'
            remaining = misc.round2(remaining * display_factor)
            display_current = current * display_factor # current already applied
            if current != 0 and misc.round2(display_current) != 0
                current = misc.round2(display_current)

            # user has no upgrades on their account
            <NoUpgrades cancel={@props.cancel_upgrading} />
        else
            {limits, remaining, current, totals, proj_remainder} = @get_quota_info()

            <Alert bsStyle='warning' style={@props.style}>
                {<React.Fragment>
