{"record":{"id":"dc6095b44b21c0d5","repo":"docling-project/docling","slug":"engine-not-initialized-call-initialize-first-dc6095","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/image_classification/transformers_engine.py","lineNumber":166,"sourceCode":"            raise RuntimeError(f\"Failed to load model from {model_folder}: {exc}\")\n\n        self._initialized = True\n        _log.info(\n            \"Transformers image-classification engine ready (device=%s, dtype=%s)\",\n            self._device,\n            self._model.dtype,  # type: ignore[union-attr]\n        )\n\n    def predict_batch(\n        self, input_batch: List[ImageClassificationEngineInput]\n    ) -> List[ImageClassificationEngineOutput]:\n        \"\"\"Run inference on a batch of inputs.\"\"\"\n        import torch\n\n        if not input_batch:\n            return []\n        if self._model is None or self._processor is None or self._device is None:\n            raise RuntimeError(\"Engine not initialized. Call initialize() first.\")\n\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        with torch.inference_mode():\n            outputs = self._model(**inputs)  # type: ignore[operator]\n            probs_batch = torch.softmax(outputs.logits, dim=-1)\n\n        batch_outputs: List[ImageClassificationEngineOutput] = []\n        for input_item, probs_vector in zip(input_batch, probs_batch):\n            # Use topk for efficiency when top_k is specified\n            if self.options.top_k is not None:\n                k = min(self.options.top_k, len(probs_vector))\n                scores, labels = torch.topk(probs_vector, k=k)\n            else:\n                scores, labels = torch.sort(probs_vector, descending=True)\n\n            batch_outputs.append(","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/models/inference_engines/image_classification/transformers_engine.py#L148-L184","documentation":"predict_batch ran before the transformers engine finished initialization. The guard requires _model, _processor, and _device to be set; if initialize() was skipped or raised (e.g. the model failed to load), these are None and inference is refused with a clear message instead of an AttributeError.","triggerScenarios":"Calling TransformersImageClassificationEngine.predict_batch() when any of _model/_processor/_device is None — initialize() not called, or its exception (see 'Failed to load model' error) was caught and ignored before predicting.","commonSituations":"Broad try/except around initialize() in orchestration code; using the engine after an OOM or load failure; frameworks that lazily construct engines but forget the init step.","solutions":["Call engine.initialize() before any predict_batch and let failures surface (fix the underlying load error rather than continuing).","Ensure the engine is re-initialized after a failure if you implement retry logic.","Structure usage as construct -> initialize -> predict, with no exception swallowing in between."],"exampleFix":"# before\nengine = TransformersImageClassificationEngine(...)\nengine.predict_batch(batch)  # _model is None\n\n# after\nengine = TransformersImageClassificationEngine(...)\nengine.initialize()\nengine.predict_batch(batch)","handlingStrategy":"validation","validationCode":"if any(getattr(engine, attr, None) is None for attr in (\"_model\", \"_processor\", \"_device\")):\n    engine.initialize()","typeGuard":null,"tryCatchPattern":"try:\n    engine.predict_batch(batch)\nexcept RuntimeError as e:\n    if \"not initialized\" in str(e):\n        engine.initialize()\n        engine.predict_batch(batch)\n    else:\n        raise","preventionTips":["Initialize engines eagerly right after construction.","Never suppress initialize() exceptions; they indicate model/device problems that predict cannot survive.","Use one lifecycle helper for all engine backends to enforce ordering."],"tags":["lifecycle","initialization","transformers","call-order"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}