{"record":{"id":"3bf200cffbd340a1","repo":"opendatalab/MinerU","slug":"invalid-submit-payload-exc","errorCode":null,"errorMessage":"Invalid submit payload: {exc}","messagePattern":"Invalid submit payload: (.+?)","errorType":"exception","errorClass":"UpstreamSubmissionUnavailable","httpStatus":null,"severity":"error","filePath":"mineru/cli/router.py","lineNumber":1160,"sourceCode":"                    ),\n                )\n                for upload in payload.uploads\n            ]\n        )\n        try:\n            response = client.post(\n                f\"{base_url}{TASKS_ENDPOINT}\",\n                files=multipart,\n            )\n        except httpx.HTTPError as exc:\n            raise UpstreamSubmissionUnavailable(str(exc)) from exc\n\n    if response.status_code == 202:\n        try:\n            submit_response = _parse_json_object_response(response, \"submit payload\")\n            return parse_submit_response(submit_response)\n        except ValueError as exc:\n            raise UpstreamSubmissionUnavailable(f\"Invalid submit payload: {exc}\") from exc\n    if response.status_code in HTTP_RETRYABLE_STATUS_CODES:\n        raise UpstreamSubmissionUnavailable(\n            f\"{response.status_code} {response_detail(response)}\"\n        )\n    raise UpstreamSubmissionRejected(response.status_code, response_detail(response))\n\n\nasync def submit_payload_to_upstream(\n    base_url: str,\n    payload: MultipartPayload,\n) -> dict[str, Any]:\n    return await asyncio.to_thread(submit_payload_to_upstream_sync, base_url, payload)\n\n\nasync def submit_router_task(\n    request: Request,\n    payload: MultipartPayload,\n) -> RouterTaskRecord:","sourceCodeStart":1142,"sourceCodeEnd":1178,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/cli/router.py#L1142-L1178","documentation":"Wraps the ValueError from parse_submit_response into UpstreamSubmissionUnavailable after a 202 response, so a malformed submit body is treated like a submission-availability failure. The router then marks the server as failed and may retry another upstream.","triggerScenarios":"Upstream returns 202 to POST /tasks but the body fails schema validation (non-object, missing/typed-wrong task_id/status/backend/created_at); the router converts it to UpstreamSubmissionUnavailable('Invalid submit payload: ...').","commonSituations":"Incompatible upstream MinerU build behind a load-balanced pool: one healthy-on-paper server returns a different response envelope, submissions repeatedly fail over across the pool, and eventually a 503 with the last error is returned.","solutions":["Capture the router logs showing the wrapped ValueError detail to identify exactly which field failed validation","Fix the offending upstream server's submit response (see parse_submit_response contract) or remove it from the pool","Confirm all servers in the pool run the same compatible MinerU version"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    task = client.submit(files)\nexcept UpstreamSubmissionUnavailable as exc:\n    if \"Invalid submit payload\" in str(exc):\n        log.error(\"upstream contract mismatch: %s\", exc)  # fix upstream, do not blind-retry\n    else:\n        retry_with_backoff(client.submit, files)","preventionTips":["Treat 'Invalid submit payload' as a configuration bug, not a transient error — do not retry","Log the wrapped ValueError detail to identify the offending field immediately","Pin upstream and router to compatible versions; test the contract on deploy"],"tags":["mineru","router","upstream","failover","validation"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}