opendatalab/MinerU · error · ValueError

max_concurrent_requests must be a positive integer

Error message

max_concurrent_requests must be a positive integer

What it means

ValueError from resolve_submit_concurrency(): max_concurrent_requests must be a positive integer; zero or negative values are rejected because the submit loop would otherwise make no progress (min() is clamped to at least 1, but only after the positivity check).

Source

Thrown at mineru/cli/client.py:767

async def download_result_zip(
    client: httpx.AsyncClient,
    submit_response: SubmitResponse,
    planned_task: PlannedTask,
) -> Path:
    return await _api_client.download_result_zip(
        client=client,
        submit_response=submit_response,
        task_label=format_task_label(planned_task),
    )


def safe_extract_zip(zip_path: Path, output_dir: Path) -> None:
    _api_client.safe_extract_zip(zip_path, output_dir)


def resolve_submit_concurrency(max_concurrent_requests: int, task_count: int) -> int:
    if max_concurrent_requests <= 0:
        raise ValueError("max_concurrent_requests must be a positive integer")
    return max(1, min(max_concurrent_requests, task_count))


def resolve_effective_max_concurrent_requests(
    local_max: int,
    server_max: int,
) -> int:
    return _api_client.resolve_effective_max_concurrent_requests(
        local_max=local_max,
        server_max=server_max,
    )


async def execute_planned_tasks(
    planned_tasks: list[PlannedTask],
    concurrency: int,
    task_runner: Callable[[PlannedTask], Awaitable[None]],
) -> list[TaskFailure]:

View on GitHub (pinned to 4fe4bde114)

Solutions

  1. Pass a positive integer (e.g. 4 or 8)
  2. Treat 0/'auto' in your wrapper by substituting a sensible default before calling mineru
  3. Guard against empty-string env vars that int() to exceptions or default to 0

Example fix

# before
concurrency = resolve_submit_concurrency(max_concurrent_requests=0, task_count=10)

# after
concurrency = resolve_submit_concurrency(max_concurrent_requests=4, task_count=10)
Defensive patterns

Strategy: validation

Validate before calling

if not isinstance(max_concurrent_requests, int) or isinstance(max_concurrent_requests, bool) or max_concurrent_requests <= 0:
    max_concurrent_requests = 4  # sane default instead of failing at submit time

Type guard

def is_positive_int(v) -> bool:
    return isinstance(v, int) and not isinstance(v, bool) and v > 0

Prevention

When it happens

Trigger: Invoking the CLI batch submit path with --max-concurrent-requests 0 or a negative number; programmatically passing max_concurrent_requests=0 intending 'auto'.

Common situations: Users expecting 0 to mean 'let the tool decide'; CI configs templating an unset variable that expands to 0; arithmetic like n-1 with n=1 yielding 0.

Related errors


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