HKUDS/DeepTutor · error · MinerUError
MinerU API returned an unexpected (non-JSON) response.
Error message
MinerU API returned an unexpected (non-JSON) response.
What it means
The API response body parsed to JSON but is not an object (e.g. a JSON list, string, or null), so the business-code check cannot run.
Source
Thrown at deeptutor/services/parsing/engines/mineru/cloud.py:298
raise MinerUError(f"MinerU API request failed: {exc}") from exc
_check_code(payload)
return payload
raise MinerUError("MinerU API key rotation exhausted.")
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 shutilView on GitHub (pinned to 3e82f13042)
Solutions
- Log the raw response body to see what was returned.
- Verify api_base_url targets the official v4 API.
- Remove intermediary proxies that transform responses.
Defensive patterns
Strategy: validation
Validate before calling
# post-response sanity check in your own gateway/tests
import json
def is_mineru_payload(text: str) -> bool:
try:
return isinstance(json.loads(text), dict)
except json.JSONDecodeError:
return False Try / catch
except MinerUError as e:
if "non-JSON" in str(e):
log_raw_body(); check_base_url() Prevention
- Point api_base_url only at the official v4 API.
- Avoid response-transforming proxies in front of the API.
When it happens
Trigger: response.json() returning a non-dict — endpoint returning a bare array, an HTML-to-JSON proxy artifact, or an API contract change.
Common situations: Custom api_base_url pointing at an incompatible gateway/proxy that rewrites responses.
Related errors
- MinerU API did not return an upload URL (missing batch_id/fi
- MinerU reported done but returned no full_zip_url.
- MinerU cloud mode is selected but no API token is configured
- PDF file not found: {pdf_path}
- Failed to upload PDF to MinerU: {exc}
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/422202a3d4132dea.
Report an issue: GitHub.