{"record":{"id":"9b5051605cbdb251","repo":"docling-project/docling","slug":"kserve-v2-client-is-not-initialized","errorCode":null,"errorMessage":"KServe v2 client is not initialized.","messagePattern":"KServe v2 client is not initialized\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"docling/models/inference_engines/image_classification/api_kserve_v2_engine.py","lineNumber":72,"sourceCode":"\n        if not enable_remote_services:\n            raise OperationNotAllowed(\n                \"Connections to remote services are only allowed when set explicitly. \"\n                \"pipeline_options.enable_remote_services=True.\"\n            )\n\n    def _resolve_model_name(self) -> str:\n        if self.options.model_name:\n            return self.options.model_name\n\n        return self._repo_id.replace(\"/\", \"--\")\n\n    def _resolve_model_version(self) -> Optional[str]:\n        return self.options.model_version\n\n    def _resolve_tensor_names(self) -> tuple[str, str]:\n        if self._kserve_client is None:\n            raise RuntimeError(\"KServe v2 client is not initialized.\")\n\n        metadata = self._kserve_client.get_model_metadata()\n        if not metadata.inputs:\n            raise RuntimeError(\n                f\"Expected image-classification model metadata to expose at least 1 input, \"\n                f\"got {len(metadata.inputs)} inputs.\"\n            )\n        if not metadata.outputs:\n            raise RuntimeError(\n                f\"Expected image-classification model metadata to expose at least 1 output, \"\n                f\"got {len(metadata.outputs)} outputs.\"\n            )\n\n        input_name = metadata.inputs[0].name\n        output_name = metadata.outputs[0].name\n        return input_name, output_name\n\n    def initialize(self) -> None:","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/models/inference_engines/image_classification/api_kserve_v2_engine.py#L54-L90","documentation":"The engine tried to resolve input/output tensor names from model metadata but the internal KServe v2 client (_kserve_client) is None, meaning initialize() has not completed (or failed before creating the client). Docling lazily creates the client during initialization, so any name resolution before that is a programming-order error.","triggerScenarios":"Calling _resolve_tensor_names (directly, or via predict_batch before initialize(), or after an initialize() that raised before client creation) on ApiKserveV2ImageClassificationEngine.","commonSituations":"Calling predict() on an engine whose initialize() raised earlier (e.g. unreachable endpoint) and the exception was swallowed; reusing an engine object after close(); custom orchestration code that skips initialize().","solutions":["Call engine.initialize() and let it raise on connection failure before any inference; do not swallow initialization exceptions.","If the failure persists, check that the KServe endpoint URL/inference_url is reachable and credentials are valid so client creation succeeds.","Do not call the engine after close(); create a fresh engine instance instead."],"exampleFix":"# before\nengine = ApiKserveV2ImageClassificationEngine(...)\nresults = engine.predict_batch(batch)  # client is None\n\n# after\nengine = ApiKserveV2ImageClassificationEngine(...)\nengine.initialize()\nresults = engine.predict_batch(batch)","handlingStrategy":"validation","validationCode":"if getattr(engine, \"_kserve_client\", None) is None or not engine._initialized:\n    raise RuntimeError(\"engine not ready — call initialize() first\")","typeGuard":null,"tryCatchPattern":"try:\n    engine.initialize()\n    engine.predict_batch(batch)\nexcept RuntimeError as e:\n    if \"not initialized\" in str(e) or \"KServe v2 client\" in str(e):\n        engine.initialize()  # single recovery attempt\n        engine.predict_batch(batch)\n    else:\n        raise","preventionTips":["Initialize engines immediately after construction in one place.","Never wrap initialize() in a silent except; treat init failure as fatal for that engine instance.","Add a lifecycle helper that returns an initialized engine or fails loudly."],"tags":["lifecycle","initialization","kserve","null-client"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}