opendatalab/MinerU · error · ValueError
local_max and server_max must both be positive integers
Error message
local_max and server_max must both be positive integers
What it means
resolve_effective_max_concurrent_requests() computes min(local_max, server_max) and requires both bounds to be strictly positive. Passing zero or a negative number (or None coerced to 0) for either limit raises immediately, since a non-positive concurrency cap is meaningless.
Source
Thrown at mineru/cli/api_client.py:703
i += 1
continue
remaining_args.append(arg)
i += 1
return tuple(remaining_args)
def normalize_base_url(url: str) -> str:
return url.rstrip("/")
def resolve_effective_max_concurrent_requests(
local_max: int,
server_max: int,
) -> int:
if local_max <= 0 or server_max <= 0:
raise ValueError(
"local_max and server_max must both be positive integers"
)
return min(local_max, server_max)
def response_detail(response: httpx.Response) -> str:
try:
payload = response.json()
except Exception:
text = response.text.strip()
return text or response.reason_phrase
if isinstance(payload, dict):
detail = payload.get("detail")
if isinstance(detail, str):
return detail
error = payload.get("error")
if isinstance(error, str):View on GitHub (pinned to 4fe4bde114)
Solutions
- Pass a positive integer; use a large number (e.g. 10**6) if you want 'effectively unlimited'
- If the value comes from a server response, default it to a sane positive value, not 0, when the field is missing
- Validate CLI input before submission (see resolve_submit_concurrency which raises the sibling error)
- Check that arithmetic on limits (e.g. max-1) never lands on 0
Example fix
# before effective = resolve_effective_max_concurrent_requests(local_max=0, server_max=8) # after effective = resolve_effective_max_concurrent_requests(local_max=8, server_max=8)
Defensive patterns
Strategy: validation
Validate before calling
def safe_effective_max(local_max: int, server_max: int, default: int = 4) -> int:
local_max = local_max if isinstance(local_max, int) and local_max > 0 else default
server_max = server_max if isinstance(server_max, int) and server_max > 0 else default
return min(local_max, server_max) Type guard
def is_positive_int(v) -> bool:
return isinstance(v, int) and not isinstance(v, bool) and v > 0 Try / catch
try:
effective = resolve_effective_max_concurrent_requests(local_max, server_max)
except ValueError:
effective = min(local_max or 4, server_max or 4) or 4 # last-resort sane default Prevention
- Never use 0 to mean 'unlimited' — use a large bound like 10**6
- Default missing server fields to a positive value when parsing responses
- Assert positivity of any concurrency knob right after CLI/config parsing
When it happens
Trigger: Calling the function with local_max=0 or server_max=0 (e.g. a CLI flag --max-concurrent-requests 0, or a server-reported limit parsed as 0 because the field was missing in the JSON response).
Common situations: Users setting concurrency to 0 expecting 'unlimited'; server responses where the max-concurrency field is absent and int(payload.get('max_concurrent_requests', 0)) defaults to 0; config files with -1 as a 'disabled' sentinel.
Related errors
- max_concurrent_requests must be a positive integer
- effort must be "medium" or "high"
- pdf_bytes_list, image_writer_list, and lang_list must have t
- Unsupported lmdeploy device type: {device_type}
- Invalid parse_method. Allowed values: {allowed_values}
AI-assisted analysis of opendatalab/MinerU@4fe4bde114 (2026-08-14).
Data as JSON: /api/errors/86a55a0f0d422dbf.
Report an issue: GitHub.