{"record":{"id":"4c4cb5ec9a791d02","repo":"keras-team/keras","slug":"the-endpoint-call-endpoint-is-neither-an-attri","errorCode":null,"errorMessage":"The endpoint '{call_endpoint}' is neither an attribute of the reloaded SavedModel, nor an entry in the `signatures` field of the reloaded SavedModel. Select another endpoint via the `call_endpoint` argument. Available endpoints for this SavedModel: {list(self._reloaded_obj.signatures.keys())}","messagePattern":"The endpoint '(.+?)' is neither an attribute of the reloaded SavedModel, nor an entry in the `signatures` field of the reloaded SavedModel\\. Select another endpoint via the `call_endpoint` argument\\. Available endpoints for this SavedModel: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/export/tfsm_layer.py","lineNumber":81,"sourceCode":"\n        # Initialize an empty layer, then add_weight() etc. as needed.\n        super().__init__(trainable=trainable, name=name, dtype=dtype)\n\n        self._reloaded_obj = tf.saved_model.load(filepath)\n\n        self.filepath = filepath\n        self.call_endpoint = call_endpoint\n        self.call_training_endpoint = call_training_endpoint\n\n        # Resolve the call function.\n        if hasattr(self._reloaded_obj, call_endpoint):\n            # Case 1: it's set as an attribute.\n            self.call_endpoint_fn = getattr(self._reloaded_obj, call_endpoint)\n        elif call_endpoint in self._reloaded_obj.signatures:\n            # Case 2: it's listed in the `signatures` field.\n            self.call_endpoint_fn = self._reloaded_obj.signatures[call_endpoint]\n        else:\n            raise ValueError(\n                f\"The endpoint '{call_endpoint}' \"\n                \"is neither an attribute of the reloaded SavedModel, \"\n                \"nor an entry in the `signatures` field of \"\n                \"the reloaded SavedModel. Select another endpoint via \"\n                \"the `call_endpoint` argument. Available endpoints for \"\n                \"this SavedModel: \"\n                f\"{list(self._reloaded_obj.signatures.keys())}\"\n            )\n\n        # Resolving the training function.\n        if call_training_endpoint:\n            if hasattr(self._reloaded_obj, call_training_endpoint):\n                self.call_training_endpoint_fn = getattr(\n                    self._reloaded_obj, call_training_endpoint\n                )\n            elif call_training_endpoint in self._reloaded_obj.signatures:\n                self.call_training_endpoint_fn = self._reloaded_obj.signatures[\n                    call_training_endpoint","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/export/tfsm_layer.py#L63-L99","documentation":"TFSMLayer resolves call_endpoint by first checking attributes of the reloaded SavedModel, then its signatures dict; if neither contains the requested name it raises this ValueError listing the actually available endpoints. The endpoint name must exactly match an attribute of the loaded object or a key in reloaded.signatures. Typos, wrong casing, and endpoints that were never exported all fail here.","triggerScenarios":"keras.layers.TFSMLayer(path, call_endpoint='serve') when the model only exported 'serving_default'; using a custom signature name that was not passed to tf.saved_model.save(..., signatures={...}); passing the endpoint name of a different SavedModel version.","commonSituations":"Mismatch between the signature name used at export time (export_archive.add_endpoint(..., name='x')) and at load time; TF-Hub models whose only endpoint is 'serving_default'; renamed endpoints after retraining or re-export.","solutions":["Read the error message: it lists the valid endpoints; use one of those names for call_endpoint.","Inspect before loading: m = tf.saved_model.load(path); print(list(m.signatures.keys())) and dir(m) for attribute endpoints.","Re-export with an explicit signature name and use that same name on both sides."],"exampleFix":"# before\nlayer = TFSMLayer('saved_model/', call_endpoint='predict')  # -> ValueError\n\n# after\nimport tensorflow as tf\nprint(list(tf.saved_model.load('saved_model/').signatures.keys()))  # e.g. ['serving_default']\nlayer = TFSMLayer('saved_model/', call_endpoint='serving_default')","handlingStrategy":"validation","validationCode":"import tensorflow as tf\nloaded = tf.saved_model.load(path)\nvalid = set(loaded.signatures.keys()) | {a for a in dir(loaded) if not a.startswith('_')}\nassert call_endpoint in valid, f'use one of {sorted(valid)}'","typeGuard":null,"tryCatchPattern":"try:\n    layer = TFSMLayer(path, call_endpoint=name)\nexcept ValueError as e:\n    # the message lists available endpoints; parse it or surface it to the user\n    raise","preventionTips":["Print signatures.keys() once when onboarding a new SavedModel.","Define signature names as shared constants used at both export and load time.","Treat the error text as the source of truth for valid names."],"tags":["keras","tfsmlayer","savedmodel","endpoint","validation"],"backgroundTag":"invalid-endpoint-name","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}