apivalidationedge-casesdeveloper-guidearchitecture

Handling Extreme Inputs in Body Measurement Applications

· 6 min read · Martin Hejda

Most users are between 155cm and 195cm and weigh between 50kg and 100kg. Your validation logic handles them fine. The problems appear at the edges: the 6’11” user who enters height in feet instead of cm and gets 83, the bariatric patient with BMI 52, the athlete with BMI 15 and 8% body fat. These cases don’t break the API, but they need different handling than the typical case.


What counts as an extreme input

Extremity isn’t absolute — it’s relative to what the model was trained on and what it can predict reliably.

Height extremes:

  • Below ~145cm in adults: outside the range of most training datasets; predictions extrapolate
  • Above ~205cm: similarly sparse in training data
  • Below 100cm: almost certainly a unit error (user entered cm as inches or vice versa)

Weight extremes:

  • Below ~40kg in adults: underweight territory where training data representation is thin
  • Above ~150kg: sparse in many datasets; predictions degrade

BMI extremes:

  • Below 15: consistent with severe malnutrition or anorexia; model may extrapolate poorly
  • Above 45: bariatric range; circumference predictions become less reliable
  • Below 10 or above 80: almost certainly an input error

Inconsistent combinations:

  • Height 180cm, weight 20kg: physiologically impossible in adults
  • Height 150cm, weight 200kg: outside prediction range for most models
  • These combinations signal either input error or a population the model wasn’t designed for

Layer 1: Client-side validation

Catch obvious errors before they reach the API. Client-side validation should be fast and user-friendly — not a barrier, but a helpful correction mechanism.

function validateMeasurements(heightCm, weightKg, gender, ageCategory = 'ADULT') {
  const errors = [];
  const warnings = [];
  
  // Absolute range checks (likely input errors)
  if (heightCm < 50 || heightCm > 280) {
    errors.push({
      field: 'height',
      message: `Height ${heightCm}cm seems outside any plausible range. Check units — are you entering in cm?`,
      severity: 'error'
    });
  }
  
  if (weightKg < 1 || weightKg > 500) {
    errors.push({
      field: 'weight', 
      message: `Weight ${weightKg}kg seems implausible. Check units — are you entering in kg?`,
      severity: 'error'
    });
  }
  
  if (errors.length > 0) return { valid: false, errors, warnings };
  
  // Soft range checks for adults (likely extrapolation territory)
  if (ageCategory === 'ADULT') {
    if (heightCm < 145) {
      warnings.push({
        field: 'height',
        message: 'Short stature noted. Predictions are less precise for heights below 145cm.',
        severity: 'warning'
      });
    }
    if (heightCm > 210) {
      warnings.push({
        field: 'height',
        message: 'Tall stature noted. Predictions are less precise for heights above 210cm.',
        severity: 'warning'
      });
    }
    
    // BMI consistency check
    const bmi = weightKg / (heightCm / 100) ** 2;
    if (bmi < 12) {
      errors.push({
        field: 'weight',
        message: 'The height/weight combination appears implausible. Please double-check both values.',
        severity: 'error'
      });
    } else if (bmi < 16) {
      warnings.push({
        field: 'weight',
        message: 'Very low body mass for this height. Predictions may be less accurate.',
        severity: 'warning'
      });
    } else if (bmi > 50) {
      warnings.push({
        field: 'weight',
        message: 'High BMI range. Predictions are less precise at extreme body compositions.',
        severity: 'warning'
      });
    }
  }
  
  // Unit detection heuristics
  if (heightCm >= 100 && heightCm <= 120 && ageCategory === 'ADULT') {
    warnings.push({
      field: 'height',
      message: 'Did you mean to enter height in inches? 100–120 inches would be 254–305cm.',
      severity: 'info'
    });
  }
  
  if (heightCm >= 3 && heightCm <= 8) {
    warnings.push({
      field: 'height',
      message: 'Did you mean to enter height in feet? Try switching to ft/in input.',
      severity: 'info'
    });
  }
  
  return { valid: errors.length === 0, errors, warnings };
}

Layer 2: Server-side plausibility checks

Never rely solely on client-side validation. Implement the same checks server-side, where they can’t be bypassed:

from dataclasses import dataclass

@dataclass
class ValidationResult:
    valid: bool
    errors: list[str]
    warnings: list[str]
    corrected_height_mm: int | None = None
    corrected_weight_kg: float | None = None

def validate_and_correct(
    height_mm: int,
    weight_kg: float,
    gender: str,
    age_category: str = "ADULT"
) -> ValidationResult:
    """
    Server-side validation with auto-correction for common unit errors.
    """
    errors = []
    warnings = []
    corrected_height_mm = height_mm
    corrected_weight_kg = weight_kg
    
    height_cm = height_mm / 10
    
    # Auto-correct obvious unit errors
    # Height entered in cm instead of mm
    if 100 <= height_mm <= 250:  # Likely cm, not mm
        corrected_height_mm = height_mm * 10
        warnings.append(
            f"Height {height_mm}mm interpreted as {height_mm}cm — converted to {corrected_height_mm}mm. "
            "Use body_height in mm (e.g., 175cm → 1750mm)."
        )
        height_cm = height_mm  # The original value was in cm
    
    # Height entered in inches
    if 55 <= height_mm <= 85 and age_category == "ADULT":
        height_cm_from_inches = height_mm * 2.54
        corrected_height_mm = int(height_cm_from_inches * 10)
        warnings.append(
            f"Height {height_mm} may have been entered in inches — "
            f"corrected to {corrected_height_mm}mm ({height_cm_from_inches:.1f}cm)."
        )
        height_cm = height_cm_from_inches
    
    # Weight in pounds
    if weight_kg > 150 and weight_kg <= 700:
        weight_kg_from_lbs = weight_kg * 0.453592
        if 30 <= weight_kg_from_lbs <= 200:
            corrected_weight_kg = weight_kg_from_lbs
            warnings.append(
                f"Weight {weight_kg} may have been entered in lbs — "
                f"corrected to {corrected_weight_kg:.1f}kg."
            )
    
    # Final plausibility check after corrections
    final_height_cm = corrected_height_mm / 10
    final_bmi = corrected_weight_kg / (final_height_cm / 100) ** 2
    
    if final_bmi < 10 or final_bmi > 80:
        errors.append(
            f"BMI of {final_bmi:.1f} from the provided measurements is outside any plausible range. "
            "Check that height is in mm and weight is in kg."
        )
    elif final_bmi < 15:
        warnings.append(
            f"BMI of {final_bmi:.1f} is in the severe underweight range. "
            "Predictions may extrapolate beyond training data."
        )
    elif final_bmi > 50:
        warnings.append(
            f"BMI of {final_bmi:.1f} is in the morbid obesity range. "
            "Circumference predictions are less precise at this BMI."
        )
    
    return ValidationResult(
        valid=len(errors) == 0,
        errors=errors,
        warnings=warnings,
        corrected_height_mm=corrected_height_mm if corrected_height_mm != height_mm else None,
        corrected_weight_kg=corrected_weight_kg if corrected_weight_kg != weight_kg else None
    )

Layer 3: Reading the API’s biological limit response

When inputs are at the edge of the model’s reliable range, a well-designed prediction API will signal this in the response. Look for fields like biological_limit_status or equivalent confidence signals:

import requests

def call_with_extreme_awareness(
    gender: str,
    height_mm: int,
    weight_kg: float,
    region: str = "GLOBAL"
) -> dict:
    """
    Call prediction API and enrich response with extreme-input context.
    """
    response = requests.post(
        "https://dimensionspot-bodysize-engine.p.rapidapi.com/v1/predict",
        json={
            "input_data": {
                "input_unit_system": "metric",
                "subject": {"gender": gender, "input_origin_region": region},
                "anchors": {"body_height": height_mm, "body_mass": weight_kg}
            },
            "output_settings": {
                "calculation": {"target_region": region, "body_build_type": "CIVILIAN"},
                "requested_dimensions": {"bundle": "TORSO"},
                "output_format": {
                    "include_range_95": True,
                    "confidence_score_threshold": 40  # Lower threshold to still get results
                }
            }
        },
        headers={
            "X-RapidAPI-Key": "YOUR_API_KEY",
            "X-RapidAPI-Host": "dimensionspot-bodysize-engine.p.rapidapi.com"
        }
    )
    
    data = response.json()
    
    # Check for biological limit warnings in the response
    limit_status = data.get("biological_limit_status")
    
    # Assess confidence across returned dimensions
    body_dims = data.get("body_dimensions", {})
    low_confidence_dims = [
        dim_id for dim_id, d in body_dims.items()
        if d.get("confidence_score", 100) < 60
    ]
    
    context = {
        "biological_limit_status": limit_status,
        "low_confidence_dimensions": low_confidence_dims,
        "result_reliability": "reduced" if (limit_status or low_confidence_dims) else "normal"
    }
    
    data["extreme_input_context"] = context
    return data

Handling the extreme case in your UX

When inputs are extreme, the right response depends on the severity:

Definite input error (BMI <10 or >80, height in implausible range): Block submission and prompt correction. Don’t make an API call.

Likely input error (height 90mm, probably entered in cm): Auto-correct with a visible notice. Proceed to prediction, but show the user what you corrected.

Edge of reliable prediction (BMI 45, height 207cm): Make the prediction, but surface the reduced confidence. Use the range_95 interval rather than the point prediction as the basis for sizing decisions — when uncertainty is high, show the user two adjacent sizes rather than committing to one.

Specialist populations (competitive athletes with high muscle mass, post-bariatric surgery, limb differences): For these users, statistical predictions from height and weight may be structurally unsuitable. The honest response is to acknowledge this and direct them to self-measurement tools: “For best results with your body type, we recommend measuring your chest, waist, and hip directly.”


Logging extreme inputs for model feedback

Extreme inputs that produce low-confidence predictions are valuable training signals. If you have a feedback mechanism (return data, user corrections), track the correlation:

def log_extreme_prediction(
    height_mm: int,
    weight_kg: float,
    prediction_result: dict,
    user_id: str | None = None
) -> None:
    """
    Log cases where prediction confidence was reduced due to extreme inputs.
    These cases help identify where model coverage needs improvement.
    """
    height_cm = height_mm / 10
    bmi = weight_kg / (height_cm / 100) ** 2
    
    body_dims = prediction_result.get("body_dimensions", {})
    avg_confidence = sum(d.get("confidence_score", 0) for d in body_dims.values()) / max(len(body_dims), 1)
    
    if bmi < 17 or bmi > 45 or height_cm < 148 or height_cm > 208 or avg_confidence < 65:
        _write_to_monitoring({
            "type": "extreme_input_prediction",
            "height_cm": height_cm,
            "weight_kg": weight_kg,
            "bmi": round(bmi, 1),
            "avg_confidence": round(avg_confidence, 1),
            "biological_limit_status": prediction_result.get("biological_limit_status"),
            "user_id": user_id  # For return correlation, if available
        })

Extreme inputs are a small fraction of your traffic but a disproportionate source of user experience failures and of bad size recommendations. The investment in explicit handling — validation layers, auto-correction, confidence-aware UX — pays off in reduced returns and increased trust from the users who are most at risk of getting wrong recommendations.

Try DimensionsPot

Free tier — 100 requests/month, no credit card required.

Get API on RapidAPI