HKUDS/DeepTutor · error · MinerUError

MinerU API error (code {code}): {msg}

Error message

MinerU API error (code {code}): {msg}

What it means

MinerU returns HTTP 200 but wraps failures in a business code; payload['code'] was non-zero (and not None), with the server's msg attached.

Source

Thrown at deeptutor/services/parsing/engines/mineru/cloud.py:302


def _post_json(client: httpx.Client, path: str, body: dict, key_pool: KeyPool) -> dict:
    return _request_json(client.post, path, key_pool, json=body)


def _get_json(client: httpx.Client, path: str, key_pool: KeyPool) -> dict:
    return _request_json(client.get, path, key_pool)


def _check_code(payload: dict) -> None:
    """MinerU wraps errors in ``{"code": <non-zero>, "msg": ...}`` even on
    HTTP 200, so the business code must be inspected explicitly."""
    if not isinstance(payload, dict):
        raise MinerUError("MinerU API returned an unexpected (non-JSON) response.")
    code = payload.get("code")
    if code not in (0, None):
        msg = str(payload.get("msg") or "unknown error")
        raise MinerUError(f"MinerU API error (code {code}): {msg}")


def _http_error_message(exc: httpx.HTTPStatusError) -> str:
    status = exc.response.status_code
    if status in (401, 403):
        return "MinerU API rejected the token (401/403). Check the API token in Settings → MinerU."
    if status == 429:
        return "MinerU API rate limit hit (429). Try again later or reduce request volume."
    return f"MinerU API returned HTTP {status}."


def _reset_dir(path: Path) -> None:
    if path.exists():
        import shutil

        shutil.rmtree(path)
    path.mkdir(parents=True, exist_ok=True)

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Read (code, msg) — they map to MinerU's documented error codes.
  2. Fix the named cause: token, quota, or parameter values.
  3. Retry after resolving; codes like quota errors clear with time/upgrade.
Defensive patterns

Strategy: try-catch

Validate before calling

# pre-validate the params you control
assert cfg.model_version in {"v2", "pipeline"}, cfg.model_version

Try / catch

except MinerUError as e:
    m = re.search(r"code (\d+)", str(e))
    if m and m.group(1) in QUOTA_CODES:
        notify_quota(); backoff()
    else:
        surface_error(str(e))

Prevention

When it happens

Trigger: _check_code seeing code like 401 (invalid token), quota errors, invalid parameters, or file-rejected — all with HTTP 200.

Common situations: Classic MinerU pattern: quota exceeded, token invalid, or bad request params (model_version, enable_formula) that still return 200.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/ae075ae7c7683226. Report an issue: GitHub.