# How to Define and Validate Parameter Bounds (min/max) in Hypster

> Learn to define and validate parameter bounds min max in Hypster using min and max arguments with hp int and hp float functions Hypster handles input validation automatically

- Repository: [Gilad Rubin/hypster](https://github.com/gilad-rubin/hypster)
- Tags: how-to-guide
- Published: 2026-03-02

---

**Use the `min` and `max` arguments in `hp.int()`, `hp.float()`, `hp.multi_int()`, or `hp.multi_float()` to restrict numeric ranges, and Hypster automatically validates inputs against these bounds through the `ParameterValidator` class in [`src/hypster/hp_calls.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp_calls.py).**

Hypster, the open-source configuration library from `gilad-rubin/hypster`, provides built-in **bounds validation** for numeric hyperparameters. By specifying `min` and `max` constraints when defining parameters in your configuration functions, you enforce operational limits without writing manual validation logic, ensuring that integer, float, and multi-value numeric parameters remain within acceptable ranges.

## How Parameter Bounds Work in Hypster

### Core Validation Architecture

The bounds validation system operates through a dispatcher-validator pattern across two primary modules. The **`HP` class** in [`src/hypster/hp.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp.py) acts as the dispatcher, while **validator classes** in [`src/hypster/hp_calls.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp_calls.py) perform the actual numeric comparisons.

When you call a numeric parameter method like `hp.int()` or `hp.float()`, the system packages your `min` and `max` arguments into specification objects (`SingleValueSpec` or `MultiValueSpec`). These specifications travel through the execution chain until they reach the validation layer.

### The Validation Flow

In [`src/hypster/hp.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp.py) (lines 47–50), the `_handle_single_value` method detects whether bounds were provided and forwards them to the validator:

```python
if (min is not None or max is not None) and hasattr(validator, "validate_bounds"):
    validator.validate_bounds(validated_value, min, max, full_path)

```

The **`ParameterValidator.validate_bounds`** method in [`src/hypster/hp_calls.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp_calls.py) (lines 26–50) performs the actual comparison and raises a descriptive `HPCallError` when violations occur:

```python
if min_val is not None and value < min_val:
    raise HPCallError(...)
if max_val is not None and value > max_val:
    raise HPCallError(...)

```

For multi-value parameters, the **`MultiValidator.validate_bounds`** method (lines 55–62) iterates over each element and delegates to the element validator, providing index-specific error reporting:

```python
for i, value in enumerate(values):
    self.element_validator.validate_bounds(value, min_val, max_val, f"{param_path}[{i}]")

```

## Defining Min/Max Constraints in Practice

### Single Numeric Parameters

The **`HP._int`** and **`HP._float`** methods accept optional `min` and `max` arguments that define inclusive bounds. These parameters work with the `strict` argument to simultaneously enforce type safety and numeric ranges.

```python
def config(hp):
    # Integer between 1 and 5 (inclusive)

    batch = hp.int(3, name="batch_size", min=1, max=5)
    
    # Float between 0.0 and 1.0 with strict type checking

    lr = hp.float(0.01, name="learning_rate", min=0.0, max=1.0, strict=True)
    
    return {"batch_size": batch, "lr": lr}

```

### Multi-Value Numeric Lists

For list-based parameters, **`hp.multi_int()`** and **`hp.multi_float()`** apply bounds validation to every element individually. If any list item violates the constraints, Hypster raises an error indicating the specific index that failed validation.

```python
def config(hp):
    # Each layer size must be between 10 and 100

    layers = hp.multi_int([20, 30], name="layer_sizes", min=10, max=100)
    return {"layers": layers}

```

Passing `[5, 20]` triggers:

```

Parameter 'layer_sizes': invalid item at index 0: value 5 is below minimum bound 10

```

### Default Value Validation

Bounds apply equally to user-provided values and **default values**. If you define a parameter with `hp.int(50, name="epochs", min=10, max=200)` and the user does not override it, Hypster validates that the default `50` satisfies the constraints before returning the configuration.

## Code Examples

### Basic Integer Bounds

Define a parameter restricted to a specific operational range:

```python
def config(hp):
    epochs = hp.int(10, name="training_epochs", min=1, max=100)
    return {"epochs": epochs}

```

- **Valid**: `training_epochs=50` succeeds
- **Invalid**: `training_epochs=0` raises `HPCallError: Parameter 'training_epochs': value 0 is below minimum bound 1`

### Float Constraints with Precision

Control continuous hyperparameters like learning rates with tight bounds:

```python
def config(hp):
    dropout = hp.float(0.2, name="dropout_rate", min=0.0, max=0.9)
    return {"dropout": dropout}

```

The bounds are **inclusive**, so values `0.0` and `0.9` are accepted, while `0.95` triggers a maximum bound violation.

### Multi-Parameter Validation

Validate entire arrays of numeric values, such as neural network layer dimensions:

```python
def config(hp):
    hidden_units = hp.multi_int([64, 128, 256], name="hidden_units", min=32, max=512)
    return {"units": hidden_units}

```

Each element in `[64, 128, 256]` is checked individually against the `min=32` and `max=512` constraints.

### Combining Bounds with Strict Typing

Prevent implicit type coercion while maintaining numeric ranges:

```python
def config(hp):
    temperature = hp.float(1.0, name="temp", min=0.1, max=2.0, strict=True)
    return {"temp": temperature}

```

With `strict=True`, passing `temp=1` (integer) fails type validation before bounds checking occurs, ensuring type safety alongside range constraints.

## Summary

- **Bounds arguments**: Use `min` and `max` in `hp.int()`, `hp.float()`, `hp.multi_int()`, and `hp.multi_float()` to define inclusive numeric ranges.
- **Automatic validation**: The `HP` class in [`src/hypster/hp.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp.py) automatically dispatches bounds to validators in [`src/hypster/hp_calls.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp_calls.py) when parameters are processed.
- **Error handling**: Violations raise `HPCallError` with descriptive messages indicating whether the failure occurred on a single value or a specific index in a multi-value list.
- **Default protection**: Bounds apply to default values, ensuring that unspecified parameters still satisfy operational constraints.
- **Extensibility**: Any custom validator implementing `validate_bounds` automatically gains min/max support through Hypster's dispatcher logic.

## Frequently Asked Questions

### What types of parameters support min and max bounds in Hypster?

**Integer, float, and their multi-value variants** support bounds validation. Specifically, use `hp.int()`, `hp.float()`, `hp.multi_int()`, or `hp.multi_float()` with the `min` and `max` arguments. Non-numeric types like booleans or strings do not support these constraints, as the validation logic resides in numeric-specific validators within [`src/hypster/hp_calls.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp_calls.py).

### Are the min and max bounds inclusive or exclusive?

The bounds are **inclusive**. According to the validation logic in [`src/hypster/hp_calls.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp_calls.py), a value equal to `min` or `max` passes validation; only values strictly less than `min` or strictly greater than `max` trigger an `HPCallError`. The code explicitly checks `value < min_val` and `value > max_val` to determine violations.

### What error does Hypster raise when bounds are violated?

Hypster raises an **`HPCallError`** with a descriptive message indicating the parameter name, the offending value, and the bound that was breached. For multi-value parameters, the error includes the specific index where the violation occurred (e.g., `invalid item at index 0: value 5 is below minimum bound 10`).

### Do min/max constraints apply to default parameter values?

**Yes**, bounds are enforced against default values. If you define `hp.int(50, name="epochs", min=10, max=200)` and do not provide a value for `epochs` in your input dictionary, Hypster validates that the default `50` satisfies the `min=10` and `max=200` constraints before returning the final configuration object.