{"record":{"id":"23fe89ac8684e1fc","repo":"opendatalab/MinerU","slug":"middle-json-must-be-a-dict","errorCode":null,"errorMessage":"middle_json must be a dict.","messagePattern":"middle_json must be a dict\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mineru/cli/client_side_output.py","lineNumber":60,"sourceCode":"\n\ndef regenerate_client_side_outputs(\n    parse_dir: str | Path,\n    doc_stem: str,\n) -> tuple[Path, ...]:\n    \"\"\"读取服务端 staged/finalized middle json，并在客户端覆盖生成最终输出产物。\"\"\"\n    parse_dir = Path(parse_dir)\n    middle_json_path = parse_dir / f\"{doc_stem}_middle.json\"\n    markdown_path = parse_dir / f\"{doc_stem}.md\"\n    content_list_path = parse_dir / f\"{doc_stem}_content_list.json\"\n    content_list_v2_path = parse_dir / f\"{doc_stem}_content_list_v2.json\"\n\n    if not middle_json_path.exists():\n        raise FileNotFoundError(f\"Missing middle json file: {middle_json_path}\")\n\n    middle_json = json.loads(middle_json_path.read_text(encoding=\"utf-8\"))\n    if not isinstance(middle_json, dict):\n        raise ValueError(\"middle_json must be a dict.\")\n    backend = middle_json.get(\"_backend\")\n    pdf_info = middle_json.get(\"pdf_info\")\n    if backend not in SUPPORTED_BACKENDS:\n        raise ValueError(\n            f\"Unsupported middle json backend for client-side output generation: {backend}\"\n        )\n    if not isinstance(pdf_info, list):\n        raise ValueError(\"middle_json must contain a list field named pdf_info.\")\n\n    if backend in PDF_BACKENDS:\n        finalize_client_side_middle_json(middle_json)\n        pdf_info = middle_json[\"pdf_info\"]\n\n    make_func = _select_union_make(backend)\n    image_dir = \"images\"\n\n    markdown_path.write_text(\n        make_func(pdf_info, MakeMode.MM_MD, image_dir),","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/cli/client_side_output.py#L42-L78","documentation":"ValueError from regenerate_client_side_outputs(): after json.loads of the middle json, the top-level value must be a dict (the code immediately reads .get('_backend') and .get('pdf_info')). A JSON array, string, number, or null at the top level fails this check.","triggerScenarios":"A {doc}_middle.json whose top level is a list (e.g. a bare pdf_info array serialized by an old version or a custom exporter) or a truncated/corrupted file that still parses as valid non-dict JSON (rare); most corruption instead raises JSONDecodeError one line earlier.","commonSituations":"Hand-rolled middle-json producers that dump the page array directly; third-party tools writing their own _middle.json; files from very old mineru versions with a different schema.","solutions":["Regenerate the middle json with a current mineru server so it is wrapped in an object with _backend and pdf_info keys","If producing middle json yourself, emit {\"_backend\": \"pipeline\", \"pdf_info\": [...]}","Validate the shape in a pre-check before calling regenerate (see defense below)"],"exampleFix":"# before: middle.json contains just [ {...page1...}, {...page2...} ]\n\n# after: {\"_backend\": \"pipeline\", \"pdf_info\": [ {...page1...}, {...page2...} ]}","handlingStrategy":"type-guard","validationCode":"payload = json.loads(middle_json_path.read_text(encoding=\"utf-8\"))\nif not isinstance(payload, dict):\n    raise SystemExit(\"middle json schema mismatch: top level must be an object; regenerate with current mineru\")","typeGuard":"def is_middle_json_dict(payload: object) -> bool:\n    return isinstance(payload, dict)","tryCatchPattern":"try:\n    regenerate_client_side_outputs(parse_dir, doc_stem)\nexcept ValueError as e:\n    if \"must be a dict\" in str(e):\n        refetch_results()  # schema is foreign/stale; do not try to patch it\n    else:\n        raise","preventionTips":["Never hand-write middle.json; always produce it via mineru","If post-processing, round-trip through json and assert the object shape","Pin server/client versions so the schema cannot drift"],"tags":["client-side","middle-json","schema","validation"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}