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

  1. Pass a positive integer; use a large number (e.g. 10**6) if you want 'effectively unlimited'
  2. If the value comes from a server response, default it to a sane positive value, not 0, when the field is missing
  3. Validate CLI input before submission (see resolve_submit_concurrency which raises the sibling error)
  4. 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

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


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