{"record":{"id":"7190116551b7c5a6","repo":"opendatalab/MinerU","slug":"images-mfd-res-and-images-must-have-the-same-lengt","errorCode":null,"errorMessage":"images_mfd_res and images must have the same length.","messagePattern":"images_mfd_res and images must have the same length\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mineru/model/mfr/pp_formulanet_plus_m/predict_formula.py","lineNumber":144,"sourceCode":"        return self.batch_predict(\n            [mfd_res],\n            [image],\n            batch_size=batch_size,\n            interline_enable=interline_enable,\n        )[0]\n\n    def batch_predict(\n        self,\n        images_mfd_res: list,\n        images: list,\n        batch_size: int = 64,\n        interline_enable: bool = True,\n    ) -> list:\n        if not images_mfd_res:\n            return []\n\n        if len(images_mfd_res) != len(images):\n            raise ValueError(\"images_mfd_res and images must have the same length.\")\n\n        images_formula_list = []\n        mf_image_list = []\n        backfill_list = []\n        image_info = []\n\n        for mfd_res, image in zip(images_mfd_res, images):\n            formula_list, crop_targets = self._build_formula_items(\n                mfd_res,\n                image,\n                interline_enable=interline_enable,\n            )\n\n            for formula_item, (xmin, ymin, xmax, ymax) in crop_targets:\n                bbox_img = image[ymin:ymax, xmin:xmax]\n                area = (xmax - xmin) * (ymax - ymin)\n\n                curr_idx = len(mf_image_list)","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/model/mfr/pp_formulanet_plus_m/predict_formula.py#L126-L162","documentation":"ValueError raised by batch_predict in the PP-FormulaNet-Plus formula recognition predictor when images_mfd_res and images have different lengths. The method zips the per-image formula-detection results with the page images, so a mismatch means detection results and pages describe different documents and processing would silently skip or mispair pages.","triggerScenarios":"Calling batch_predict(mfd_results_for_3_pages, images_of_4_pages); typically caused by appending MFD outputs across runs while rebuilding the images list from scratch (or vice versa), or dropping a failed page from one list only.","commonSituations":"Accumulating formula-detection results in a retry loop where some pages fail and are excluded from one list; parallel workers returning mismatched result/image counts; page-level filtering (blank-page skip) applied to images but not to the detection results.","solutions":["Keep both lists in lockstep: whenever a page is skipped/failed, drop its entry from both images and images_mfd_res.","Rebuild pairs from a single source of truth: iterate pages once, run MFD, and append to both lists together.","Add an assert len(images_mfd_res) == len(images) before calling batch_predict so mismatches surface at the call site."],"exampleFix":"# before\nmfd_res, images = [], original_images\nfor page in pages:\n    r = run_mfd(page)\n    mfd_res.append(r)          # appended even when page skipped from images\nbatch_predict(mfd_res, images)  # ValueError\n\n# after\nmfd_res, images = [], []\nfor page in pages:\n    r = run_mfd(page)\n    mfd_res.append(r)\n    images.append(page)         # always paired\nbatch_predict(mfd_res, images)","handlingStrategy":"validation","validationCode":"def run_batch(predictor, mfd_results: list, pages: list, **kw):\n    if len(mfd_results) != len(pages):\n        raise ValueError(\n            f'mfd results ({len(mfd_results)}) and pages ({len(pages)}) out of sync; '\n            'rebuild both lists from the same page loop'\n        )\n    return predictor.batch_predict(mfd_results, pages, **kw)","typeGuard":null,"tryCatchPattern":"try:\n    results = predictor.batch_predict(mfd_res, images)\nexcept ValueError as e:\n    if 'same length' in str(e):\n        n = min(len(mfd_res), len(images))\n        results = predictor.batch_predict(mfd_res[:n], images[:n])  # only if truncation is acceptable\n    else:\n        raise","preventionTips":["Append to images_mfd_res and images in the same loop iteration so they cannot diverge.","When skipping a page (blank, failed), skip it in both lists.","Assert equal lengths at the call site with a message naming both counts."],"tags":["formula-recognition","validation","batching","api-misuse"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}