apache/beam · error · ValueError
Cannot use an unkeyed model handler with pre or postprocessi
Error message
Cannot use an unkeyed model handler with pre or postprocessing functions defined in a keyed model handler. All pre/postprocessing functions must be defined on the outer modelhandler.
What it means
The multi-model (list) constructor of KeyedModelHandler accepts handler/key tuples; each inner handler must be free of preprocess/postprocess functions because they must be defined on the outer keyed handler. A ValueError is raised for any tuple whose handler has decorated functions.
Source
Thrown at sdks/python/apache_beam/ml/inference/base.py:785
'pre/postprocessing functions must be defined on the outer model'
'handler.')
self._env_vars = getattr(unkeyed, '_env_vars', {})
self._unkeyed = unkeyed
return
self._max_models_per_worker_hint = max_models_per_worker_hint
# To maintain an efficient representation, we will map all keys in a given
# KeyModelMapping to a single id (the first key in the KeyModelMapping
# list). We will then map that key to a ModelHandler. This will allow us to
# quickly look up the appropriate ModelHandler for any given key.
self._id_to_mh_map: dict[str, ModelHandler[ExampleT, PredictionT,
ModelT]] = {}
self._key_to_id_map: dict[str, str] = {}
for mh_tuple in unkeyed:
mh = mh_tuple.mh
keys = mh_tuple.keys
if len(mh.get_preprocess_fns()) or len(mh.get_postprocess_fns()):
raise ValueError(
'Cannot use an unkeyed model handler with pre or '
'postprocessing functions defined in a keyed model handler. All '
'pre/postprocessing functions must be defined on the outer model'
'handler.')
hints = mh.get_resource_hints()
if len(hints) > 0:
logging.warning(
'mh %s defines the following resource hints, which will be'
'ignored: %s. Resource hints 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.get_resource_hints() method.',
mh,
hints)
batch_kwargs = mh.batch_elements_kwargs()
if len(batch_kwargs) > 0:
logging.warning(
'mh %s defines the following batching kwargs which will be 'View on GitHub (pinned to 12126d8942)
Solutions
- Strip the pre/postprocessing functions from each inner handler (use undecorated instances).
- Attach the functions once on the resulting KeyedModelHandler via with_preprocess_fns/with_postprocess_fns.
- If per-model preprocessing is truly needed, implement it inside a custom ModelHandler subclass instead.
Example fix
# before mh_a = HandlerA().with_preprocess_fns(fn) keyed = KeyedModelHandler([KeyedModelHandlerTuple(mh_a, ['a'])]) # after keyed = KeyedModelHandler([KeyedModelHandlerTuple(HandlerA(), ['a'])]).with_preprocess_fns(fn)
Defensive patterns
Strategy: validation
Validate before calling
bad = [mh for mh, _ in [(t.mh, t.keys) for t in tuples] if mh.get_preprocess_fns() or mh.get_postprocess_fns()]
assert not bad, f'Inner handlers with pre/post fns: {bad}' Type guard
def all_undecorated(tuples):
return all(not t.mh.get_preprocess_fns() and not t.mh.get_postprocess_fns() for t in tuples) Try / catch
try:
keyed = KeyedModelHandler(tuples)
except ValueError as e:
if 'pre or postprocessing' in str(e):
tuples = [KeyedModelHandlerTuple(strip_fns(t.mh), t.keys) for t in tuples]
keyed = KeyedModelHandler(tuples).with_preprocess_fns(fn)
else:
raise Prevention
- Define pre/postprocessing once on the KeyedModelHandler, never per inner handler.
- When refactoring decorated handlers into keyed setups, remove decorations first.
- Assert handler tuples are undecorated in pipeline-builder utilities.
When it happens
Trigger: KeyedModelHandler([KeyedModelHandlerTuple(mh1, ['k1']), KeyedModelHandlerTuple(mh2, ['k2'])]) where mh1 or mh2 has pre/postprocess fns attached via with_preprocess_fns/with_postprocess_fns.
Common situations: Building multi-model serving setups where each cohort's handler was individually decorated; refactoring decorated handlers into keyed multi-handler configs without moving the functions outward.
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
- Cannot make make an unkeyed model handler with pre or postpr
- Cannot override RemoteModelHandler.load_model, implement cre
- Cannot override RemoteModelHandler.run_inference, implement
- Rate Limit Exceeded, Could not process this batch.
- Empty list maps to model handler {mh}. All model handlers mu
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/58a638185ca4d315.
Report an issue: GitHub.