{"record":{"id":"f324901bf4c51150","repo":"apache/beam","slug":"callable-create-model-fn-must-be-passedwith-modeltype-saved","errorCode":null,"errorMessage":"Callable create_model_fn must be passedwith ModelType.SAVED_WEIGHTS","messagePattern":"Callable create_model_fn must be passedwith ModelType\\.SAVED_WEIGHTS","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/ml/inference/tensorflow_inference.py","lineNumber":182,"sourceCode":"        max_batch_weight=max_batch_weight,\n        element_size_fn=element_size_fn,\n        batch_length_fn=batch_length_fn,\n        batch_bucket_boundaries=batch_bucket_boundaries,\n        large_model=large_model,\n        model_copies=model_copies,\n        **kwargs)\n    self._model_uri = model_uri\n    self._model_type = model_type\n    self._inference_fn = inference_fn\n    self._create_model_fn = create_model_fn\n    self._load_model_args = {} if not load_model_args else load_model_args\n    self._custom_weights = custom_weights\n\n  def load_model(self) -> tf.Module:\n    \"\"\"Loads and initializes a Tensorflow model for processing.\"\"\"\n    if self._model_type == ModelType.SAVED_WEIGHTS:\n      if not self._create_model_fn:\n        raise ValueError(\n            \"Callable create_model_fn must be passed\"\n            \"with ModelType.SAVED_WEIGHTS\")\n      return _load_model_from_weights(self._create_model_fn, self._model_uri)\n\n    return _load_model(\n        self._model_uri, self._custom_weights, self._load_model_args)\n\n  def update_model_path(self, model_path: Optional[str] = None):\n    self._model_uri = model_path if model_path else self._model_uri\n\n  def run_inference(\n      self,\n      batch: Sequence[numpy.ndarray],\n      model: tf.Module,\n      inference_args: Optional[dict[str, Any]] = None\n  ) -> Iterable[PredictionResult]:\n    \"\"\"\n    Runs inferences on a batch of numpy array and returns an Iterable of","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/ml/inference/tensorflow_inference.py#L164-L200","documentation":"Raised in TFTensorFlowModelHandler (KeyedModelHandler) load_model when model_type is ModelType.SAVED_WEIGHTS but no create_model_fn callable was supplied. Loading raw saved weights requires a callable that instantiates the model architecture into which the weights are loaded.","triggerScenarios":"Constructing the TF handler with model_type=ModelType.SAVED_WEIGHTS and leaving create_model_fn as None, then calling load_model during pipeline setup.","commonSituations":"Switching a handler from SAVED_MODEL to SAVED_WEIGHTS without adding create_model_fn; assuming weights-only loading can infer the architecture; config-driven handler construction that omits the callable for the weights type.","solutions":["Pass a create_model_fn that returns an instantiated tf.Module/keras model with the expected architecture","Use model_type=ModelType.SAVED_MODEL instead if you have a full SavedModel and don't need weight-only loading"],"exampleFix":"// before\nhandler = TFTensorFlowModelHandlerMRU(\n    model_uri='gs://bucket/weights.ckpt', model_type=ModelType.SAVED_WEIGHTS)\n// after\nhandler = TFTensorFlowModelHandlerMRU(\n    model_uri='gs://bucket/weights.ckpt',\n    model_type=ModelType.SAVED_WEIGHTS,\n    create_model_fn=lambda: MyNet())","handlingStrategy":"validation","validationCode":"def validate_tf_handler_args(model_type, create_model_fn):\n    if model_type == ModelType.SAVED_WEIGHTS and not callable(create_model_fn):\n        raise ValueError('create_model_fn must be a callable when model_type is SAVED_WEIGHTS')","typeGuard":"import collections.abc\ncreate_model_fn_is_valid = lambda fn: isinstance(fn, collections.abc.Callable)","tryCatchPattern":"try:\n    handler.load_model()\nexcept ValueError as e:\n    if 'create_model_fn' in str(e):\n        handler._create_model_fn = build_model\n        handler.load_model()\n    else:\n        raise","preventionTips":["Pair ModelType.SAVED_WEIGHTS with a create_model_fn at construction time","Add a construction-time unit test per handler/model_type combination","Default to SAVED_MODEL unless weight-only loading is explicitly required"],"tags":["tensorflow","apache-beam","ml-inference","constructor"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}