apache/beam · error · ValueError

key {key} maps to multiple model handlers. All keys must map

Error message

key {key} maps to multiple model handlers. All keys must map to exactly one model handler.

What it means

Each key in a multi-handler KeyedModelHandler must map to exactly one model handler, since the key alone determines which handler processes an element. If the same key appears in the lists of two different handlers, the routing would be ambiguous and a ValueError is raised.

Source

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

      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]],
      model: Union[ModelT, _ModelHandlerManager],
      inference_args: Optional[dict[str, Any]] = None
  ) -> Iterable[tuple[KeyT, PredictionT]]:
    if self._single_model:
      keys, unkeyed_batch = zip(*batch)
      return zip(

View on GitHub (pinned to 12126d8942)

Solutions

  1. Deduplicate keys across tuples so each key belongs to exactly one handler.
  2. Decide which handler should own the conflicting key and remove it from the other list.
  3. Add a pre-construction check that the union of key lists has no duplicates.

Example fix

# before
KeyedModelHandler([
  KeyedModelHandlerTuple(mh1, ['a', 'b']),
  KeyedModelHandlerTuple(mh2, ['b', 'c'])])

# after
KeyedModelHandler([
  KeyedModelHandlerTuple(mh1, ['a', 'b']),
  KeyedModelHandlerTuple(mh2, ['c'])])
Defensive patterns

Strategy: validation

Validate before calling

all_keys = [k for t in tuples for k in t.keys]
assert len(all_keys) == len(set(all_keys)), f'Duplicate keys across handlers: {set(k for k in all_keys if all_keys.count(k) > 1)}'

Type guard

def keys_unique(tuples):
    seen = set()
    for t in tuples:
        if seen & set(t.keys):
            return False
        seen.update(t.keys)
    return True

Try / catch

try:
    keyed = KeyedModelHandler(tuples)
except ValueError as e:
    if 'maps to multiple model handlers' in str(e):
        raise ConfigError('Deduplicate keys across cohorts') from e
    raise

Prevention

When it happens

Trigger: KeyedModelHandler([KeyedModelHandlerTuple(mh1, ['a','b']), KeyedModelHandlerTuple(mh2, ['b','c'])]) — key 'b' appears in both tuples.

Common situations: Overlapping cohorts from config files; copy-paste of key lists between handlers; generating cohorts from data where a key legitimately belongs to multiple groups but the API expects a partition.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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