# Using `options_only` with Hypster's `select` Parameters to Restrict Choices

> Learn how to use the options_only parameter with Hypster's select helpers to enforce strict whitelists and prevent invalid choices. Restrict options effectively.

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

---

**The `options_only` parameter in Hypster's `select` and `multi_select` helpers acts as a strict whitelist, raising an `HPCallError` whenever a supplied value falls outside the predefined options list.**

Hypster provides a type-safe configuration system for machine learning experiments through its `HP` API. When defining categorical parameters with `select`, the optional `options_only` Boolean flag controls whether arbitrary values are accepted or strictly limited to the predefined list. Understanding this mechanism ensures your configurations fail fast on invalid inputs rather than propagating errors downstream.

## How `options_only` Works Internally

### Specification Storage

In [`src/hypster/hp.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp.py), the `SelectSingleSpec` class stores the `options_only` flag during parameter definition (lines 81-86). For multi-select scenarios, `SelectMultiSpec` handles the equivalent logic. This specification object carries the validation requirement through the entire configuration lifecycle.

### Execution Flow

When you call `hp.select(..., options_only=True)`, the public `_select` method constructs a `SelectSingleSpec` instance and forwards it to `_execute_select_single` (lines 511-522 in [`src/hypster/hp.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp.py)). This unified executor handles both single and multi-select variants, ensuring consistent validation semantics across the API.

### Validation Logic

The actual enforcement occurs in [`src/hypster/hp_calls.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp_calls.py). The `SelectValidator.validate_value` method checks if the supplied value exists in the allowed `options` list when `options_only` is `True`. If validation fails, it raises `HPCallError` with a descriptive message listing the first few allowed options (lines 16-23). When `options_only` is `False` (the default), any value passes validation, though the library still maintains the default mapping when using dictionary-form options.

## When to Use `options_only`

| Situation | Recommended Setting |
|-----------|----------------------|
| Fixed set of supported algorithms, model names, or feature flags where unknown strings must be rejected | `options_only=True` |
| Open-ended configuration where users may supply custom values (e.g., user-defined paths, bespoke model classes) | `options_only=False` (default) |

## Practical Code Examples

### Strict Single Selection

Use `options_only=True` to limit solver selection to supported algorithms:

```python
from hypster import HP, instantiate

def model_cfg(hp: HP):
    # Strictly limited to the two supported solvers

    solver = hp.select(
        ["lbfgs", "saga"],
        name="solver",
        default="lbfgs",
        options_only=True,          # Only these two strings are accepted

    )
    # Open-ended hyper-parameter – any string is allowed

    custom_path = hp.select(
        ["default", "fast"],
        name="path_mode",
        default="default",
        options_only=False,         # User may pass an arbitrary path later

    )
    return {"solver": solver, "path_mode": custom_path}

# Valid configuration using default values

cfg = instantiate(model_cfg)

# Valid configuration selecting an allowed option

cfg2 = instantiate(model_cfg, values={"solver": "saga"})

# Invalid configuration – raises HPCallError because "adam" is not allowed

# cfg3 = instantiate(model_cfg, values={"solver": "adam"})

```

### Restricted Multi-Selection

The `options_only` parameter works identically with `multi_select`:

```python
def features_cfg(hp: HP):
    # Only allow the listed feature names; any other string will raise

    feats = hp.multi_select(
        ["price", "size", "color"],
        name="features",
        default=["price"],
        options_only=True,
    )
    return {"features": feats}

# Valid selection from the whitelist

cfg = instantiate(features_cfg, values={"features": ["price", "color"]})

# Invalid – "weight" not in the predefined options

# cfg_bad = instantiate(features_cfg, values={"features": ["weight"]})

```

### Dictionary Options with Strict Validation

When using dictionary-form options, `options_only=True` restricts selection to the defined keys:

```python
def tokenizer_cfg(hp: HP):
    # Dictionary maps short keys to concrete tokenizer objects

    # With options_only=True the user must pick one of the keys

    tokenizer = hp.select(
        {
            "none": None,
            "basic": "basic_tokenizer",
            "advanced": "advanced_tokenizer",
        },
        name="tokenizer",
        default="basic",
        options_only=True,
    )
    return {"tokenizer": tokenizer}

```

## Summary

- **`options_only=True`** enforces a strict whitelist in [`src/hypster/hp_calls.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp_calls.py), raising `HPCallError` for any value not present in the predefined options.
- **Default behavior** (`options_only=False`) accepts arbitrary values while preserving dictionary mappings for convenience.
- **Multi-select validation** applies the same rules through `SelectMultiSpec` and shared validation logic in `SelectValidator`.
- **Dictionary-form options** validate against keys when `options_only=True`, ensuring only defined configuration variants are instantiated.

## Frequently Asked Questions

### What error does Hypster raise when `options_only=True` and I provide an invalid value?

Hypster raises `HPCallError` with a message indicating the invalid value and listing the first few allowed options from the predefined list. This occurs in `SelectValidator.validate_value` within [`src/hypster/hp_calls.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp_calls.py).

### Can I use `options_only` with dictionary-style options?

Yes. When using a dictionary to map display names to actual values, setting `options_only=True` restricts the user to selecting only the defined keys. The validation occurs before the dictionary lookup, preventing access to arbitrary values.

### Does `options_only` work with `multi_select` parameters?

Yes. The `multi_select` helper accepts the same `options_only` parameter, storing it in `SelectMultiSpec` according to the source code in [`src/hypster/hp.py`](https://github.com/gilad-rubin/hypster/blob/main/src/hypster/hp.py). When enabled, every item in the provided list must exist in the predefined options or the validator raises `HPCallError`.

### What is the default value of `options_only`?

The default value is `False`, allowing open-ended configuration where users may supply values not explicitly listed in the options array. Set it to `True` only when you need strict validation against a fixed set of supported values.