{"record":{"id":"f09c94894bc410a1","repo":"docling-project/docling","slug":"engine-not-initialized-call-initialize-first-f09c94","errorCode":null,"errorMessage":"Engine not initialized. Call initialize() first.","messagePattern":"Engine not initialized\\. Call initialize\\(\\) first\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"docling/models/inference_engines/object_detection/transformers_engine.py","lineNumber":195,"sourceCode":"        )\n\n    def predict_batch(\n        self, input_batch: List[ObjectDetectionEngineInput]\n    ) -> List[ObjectDetectionEngineOutput]:\n        \"\"\"Run inference on a batch of inputs.\n\n        Args:\n            input_batch: List of input images with metadata\n\n        Returns:\n            List of detection outputs\n        \"\"\"\n        import torch\n\n        if not input_batch:\n            return []\n        if self._model is None or self._processor is None:\n            raise RuntimeError(\"Engine not initialized. Call initialize() first.\")\n\n        # Preprocess images using HF processor\n        images = [item.image.convert(\"RGB\") for item in input_batch]\n        inputs = self._processor(images=images, return_tensors=\"pt\").to(self._device)\n\n        # Get target sizes for post-processing\n        target_sizes = torch.tensor(\n            [[img.height, img.width] for img in images], device=self._device\n        )\n\n        # Run inference\n        with torch.inference_mode():\n            outputs = self._model(**inputs)  # type: ignore[operator]\n\n        # Post-process using HuggingFace processor\n        results = self._processor.post_process_object_detection(  # type: ignore[attr-defined]\n            outputs,\n            target_sizes=target_sizes,  # type: ignore[arg-type]","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/models/inference_engines/object_detection/transformers_engine.py#L177-L213","documentation":"TransformersObjectDetectionEngine.predict_batch() raises RuntimeError when self._model or self._processor is None, i.e. before initialize() has successfully loaded them. This mirrors the ONNX and KServe engines' lifecycle contract: construct, initialize, then predict.","triggerScenarios":"Calling predict_batch() on an uninitialized engine, or after a failed initialize() whose exception was caught and ignored upstream.","commonSituations":"Custom code managing engines manually; lazy-init patterns that assume predict triggers initialization; error handlers that log-and-continue past init failures.","solutions":["Call engine.initialize() before predict_batch().","Use the standard pipeline API which enforces the lifecycle.","Make initialize() failures fatal — do not call predict after any init exception."],"exampleFix":"# before\nengine = TransformersObjectDetectionEngine(options=opts, ...)\nouts = engine.predict_batch(batch)\n\n# after\nengine = TransformersObjectDetectionEngine(options=opts, ...)\nengine.initialize()\nouts = engine.predict_batch(batch)","handlingStrategy":"validation","validationCode":"if engine._model is None or engine._processor is None:\n    engine.initialize()","typeGuard":null,"tryCatchPattern":"try:\n    outs = engine.predict_batch(batch)\nexcept RuntimeError as e:\n    if \"not initialized\" in str(e):\n        engine.initialize()\n        outs = engine.predict_batch(batch)\n    else:\n        raise","preventionTips":["Construct -> initialize -> predict, always in that order.","Let the standard pipeline own engine lifecycle.","Never continue after a failed initialize()."],"tags":["lifecycle","initialization","transformers","object-detection"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}