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
- Deduplicate keys across tuples so each key belongs to exactly one handler.
- Decide which handler should own the conflicting key and remove it from the other list.
- 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
- Ensure cohort definitions partition the key space without overlap.
- Add a deduplication/assertion step when generating key lists from configs.
- Keep a single source of truth for key-to-handler assignments.
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
- Empty list maps to model handler {mh}. All model handlers mu
- Invalid model update: {key} appears in multiple update lists
- MatchContinuously interval must be positive.
- Invalid create disposition %s. Expecting %s
- Invalid write disposition %s. Expecting %s
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/667caef9c3674070.
Report an issue: GitHub.