opendatalab/MinerU · error · UpstreamSubmissionUnavailable

Invalid submit payload: {exc}

Error message

Invalid submit payload: {exc}

What it means

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.

Source

Thrown at mineru/cli/router.py:1160

                    ),
                )
                for upload in payload.uploads
            ]
        )
        try:
            response = client.post(
                f"{base_url}{TASKS_ENDPOINT}",
                files=multipart,
            )
        except httpx.HTTPError as exc:
            raise UpstreamSubmissionUnavailable(str(exc)) from exc

    if response.status_code == 202:
        try:
            submit_response = _parse_json_object_response(response, "submit payload")
            return parse_submit_response(submit_response)
        except ValueError as exc:
            raise UpstreamSubmissionUnavailable(f"Invalid submit payload: {exc}") from exc
    if response.status_code in HTTP_RETRYABLE_STATUS_CODES:
        raise UpstreamSubmissionUnavailable(
            f"{response.status_code} {response_detail(response)}"
        )
    raise UpstreamSubmissionRejected(response.status_code, response_detail(response))


async def submit_payload_to_upstream(
    base_url: str,
    payload: MultipartPayload,
) -> dict[str, Any]:
    return await asyncio.to_thread(submit_payload_to_upstream_sync, base_url, payload)


async def submit_router_task(
    request: Request,
    payload: MultipartPayload,
) -> RouterTaskRecord:

View on GitHub (pinned to 4fe4bde114)

Solutions

  1. Capture the router logs showing the wrapped ValueError detail to identify exactly which field failed validation
  2. Fix the offending upstream server's submit response (see parse_submit_response contract) or remove it from the pool
  3. Confirm all servers in the pool run the same compatible MinerU version
Defensive patterns

Strategy: try-catch

Try / catch

try:
    task = client.submit(files)
except UpstreamSubmissionUnavailable as exc:
    if "Invalid submit payload" in str(exc):
        log.error("upstream contract mismatch: %s", exc)  # fix upstream, do not blind-retry
    else:
        retry_with_backoff(client.submit, files)

Prevention

When it happens

Trigger: 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: ...').

Common situations: 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.

Related errors


AI-assisted analysis of opendatalab/MinerU@4fe4bde114 (2026-08-14). Data as JSON: /api/errors/3bf200cffbd340a1. Report an issue: GitHub.