apache/beam · error · ValueError

Empty list maps to model handler {mh}. All model handlers mu

Error message

Empty list maps to model handler {mh}. All model handlers must have one or more associated keys.

What it means

In the multi-handler KeyedModelHandler constructor, every model handler must be associated with at least one key so elements can be routed to it. An empty key list makes that handler unreachable, so a ValueError naming the offending handler is raised.

Source

Thrown at sdks/python/apache_beam/ml/inference/base.py:822

            'ignored %s. Batching kwargs are not respected when '
            'more than one model handler is used in a KeyedModelHandler. If '
            'you would like to specify resource hints, you can do so by '
            'overriding the KeyedModelHandler.batch_elements_kwargs() method.',
            hints,
            batch_kwargs)
      env_vars = getattr(mh, '_env_vars', {})
      if len(env_vars) > 0:
        logging.warning(
            'mh %s defines the following _env_vars which will be ignored %s. '
            '_env_vars are not respected when more than one model handler is '
            'used in a KeyedModelHandler. If you need env vars set at '
            'inference time, you can do so with '
            'a custom inference function.',
            mh,
            env_vars)

      if len(keys) == 0:
        raise ValueError(
            f'Empty list maps to model handler {mh}. All model handlers must '
            'have one or more associated keys.')
      self._id_to_mh_map[keys[0]] = mh
      for key in keys:
        if key in self._key_to_id_map:
          raise ValueError(
              f'key {key} maps to multiple model handlers. All keys must map '
              'to exactly one model handler.')
        self._key_to_id_map[key] = keys[0]

  def load_model(self) -> Union[ModelT, _ModelHandlerManager]:
    if self._single_model:
      return self._unkeyed.load_model()
    return _ModelHandlerManager(self._id_to_mh_map)

  def run_inference(
      self,
      batch: Sequence[tuple[KeyT, ExampleT]],

View on GitHub (pinned to 12126d8942)

Solutions

  1. Provide a non-empty list of keys for every KeyedModelHandlerTuple.
  2. Validate key lists before construction and drop (or fix) handlers with no keys.
  3. Check the source of the keys (config, side input) for empty values at pipeline-build time.

Example fix

# before
KeyedModelHandler([KeyedModelHandlerTuple(mh, cohort_keys)])  # cohort_keys == []

# after
if not cohort_keys:
  raise ValueError('cohort_keys must be non-empty')
KeyedModelHandler([KeyedModelHandlerTuple(mh, cohort_keys)])
Defensive patterns

Strategy: validation

Validate before calling

for t in tuples:
    if len(t.keys) == 0:
        raise ValueError(f'Handler {t.mh} has no associated keys')

Type guard

def all_keys_nonempty(tuples):
    return all(len(t.keys) > 0 for t in tuples)

Try / catch

try:
    keyed = KeyedModelHandler(tuples)
except ValueError as e:
    if 'Empty list maps to model handler' in str(e):
        raise ConfigError('Check cohort key config; a handler received no keys') from e
    raise

Prevention

When it happens

Trigger: KeyedModelHandler([KeyedModelHandlerTuple(mh, [])]) — a tuple whose keys argument is an empty list, e.g. keys computed dynamically from an empty cohort or an empty config list.

Common situations: Cohort keys loaded from a file/config that turned out empty; filtering code that removed all keys for a handler; programmatic construction where the keys list was initialized but never populated.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/408738d45b7e86a1. Report an issue: GitHub.