{"record":{"id":"44e0654421e891fb","repo":"opendatalab/MinerU","slug":"mineru-upstream-returned-an-invalid-submit-payload","errorCode":null,"errorMessage":"MinerU upstream returned an invalid submit payload","messagePattern":"MinerU upstream returned an invalid submit payload","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mineru/cli/router.py","lineNumber":1097,"sourceCode":"                        field_name=key,\n                        upload_name=original_name,\n                        content_type=value.content_type or \"application/octet-stream\",\n                        path=str(destination),\n                    )\n                )\n                await value.close()\n            else:\n                fields.append((key, str(value)))\n    except Exception:\n        cleanup_path(temp_dir)\n        raise\n\n    return MultipartPayload(temp_dir=temp_dir, fields=fields, uploads=uploads)\n\n\ndef parse_submit_response(payload: Any) -> dict[str, Any]:\n    if not isinstance(payload, dict):\n        raise ValueError(\"MinerU upstream returned an invalid submit payload\")\n    task_id = payload.get(\"task_id\")\n    status = payload.get(\"status\")\n    backend = payload.get(\"backend\")\n    created_at = payload.get(\"created_at\")\n    if not isinstance(task_id, str) or not isinstance(status, str) or not isinstance(backend, str):\n        raise ValueError(\"MinerU upstream returned an invalid submit payload\")\n    if created_at is not None and not isinstance(created_at, str):\n        raise ValueError(\"MinerU upstream returned an invalid submit payload\")\n    return {\n        \"task_id\": task_id,\n        \"status\": status,\n        \"backend\": backend,\n        \"file_names\": payload.get(\"file_names\", []),\n        \"created_at\": created_at or utc_now_iso(),\n        \"started_at\": payload.get(\"started_at\"),\n        \"completed_at\": payload.get(\"completed_at\"),\n        \"error\": payload.get(\"error\"),\n        \"queued_ahead\": payload.get(\"queued_ahead\") if isinstance(payload.get(\"queued_ahead\"), int) else None,","sourceCodeStart":1079,"sourceCodeEnd":1115,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/cli/router.py#L1079-L1115","documentation":"parse_submit_response raises ValueError when the upstream submit endpoint returns a 202 whose JSON body is not a JSON object (e.g. a list, string, or number). The router strictly validates the submit response shape before registering the task.","triggerScenarios":"POST {base_url}/tasks returns 202 with a top-level JSON array, string, or scalar instead of an object; or a proxy in front of the upstream rewrites the response body.","commonSituations":"A custom or incompatible MinerU upstream version that returns a different response envelope; an API gateway that transforms responses; the URL points at a non-MinerU service that accepts POSTs.","solutions":["Inspect the actual upstream response body for POST /tasks and compare with the expected {task_id, status, backend, ...} object","Verify the upstream is a compatible MinerU API server version","Remove any intermediary that rewrites the response body"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import httpx\n\ndef submit_ok(base_url: str, files) -> dict:\n    with httpx.Client() as c:\n        r = c.post(f\"{base_url}/tasks\", files=files)\n        body = r.json()\n        assert r.status_code == 202 and isinstance(body, dict), body\n        return body","typeGuard":"def is_submit_payload(v) -> bool:\n    return isinstance(v, dict)","tryCatchPattern":null,"preventionTips":["Contract-test the upstream submit response shape after every upstream upgrade","Return the error detail from UpstreamSubmissionUnavailable in client error reporting","Keep all pool members on the same MinerU version"],"tags":["mineru","router","validation","upstream","json"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}