{"record":{"id":"d34ab94c8d183632","repo":"opendatalab/MinerU","slug":"max-concurrent-requests-must-be-a-positive-integer-d34ab9","errorCode":null,"errorMessage":"max_concurrent_requests must be a positive integer","messagePattern":"max_concurrent_requests must be a positive integer","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mineru/cli/router.py","lineNumber":659,"sourceCode":"\n    def _update_server_from_health_payload(\n        self,\n        server: WorkerState,\n        payload: dict[str, Any],\n    ) -> None:\n        protocol_version = payload.get(\"protocol_version\")\n        if protocol_version != API_PROTOCOL_VERSION:\n            raise ValueError(\n                f\"Unsupported protocol_version={protocol_version}, expected {API_PROTOCOL_VERSION}\"\n            )\n\n        server.queued_tasks = int(payload.get(\"queued_tasks\", 0))\n        server.processing_tasks = int(payload.get(\"processing_tasks\", 0))\n        server.completed_tasks = int(payload.get(\"completed_tasks\", 0))\n        server.failed_tasks = int(payload.get(\"failed_tasks\", 0))\n        server.max_concurrent_requests = int(payload.get(\"max_concurrent_requests\", 0))\n        if server.max_concurrent_requests <= 0:\n            raise ValueError(\"max_concurrent_requests must be a positive integer\")\n        server.processing_window_size = max(\n            MIN_HEALTHY_PROCESSING_WINDOW_SIZE,\n            int(\n                payload.get(\n                    \"processing_window_size\",\n                    MIN_HEALTHY_PROCESSING_WINDOW_SIZE,\n                )\n            ),\n        )\n        server.healthy = payload.get(\"status\") == \"healthy\"\n        server.last_error = (\n            None if server.healthy else json.dumps(payload, ensure_ascii=False)\n        )\n        server.consecutive_health_failures = (\n            0 if server.healthy else server.consecutive_health_failures + 1\n        )\n\n    async def _refresh_server(self, server: WorkerState) -> None:","sourceCodeStart":641,"sourceCodeEnd":677,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/cli/router.py#L641-L677","documentation":"ValueError raised in router.py during health-payload processing: max_concurrent_requests (defaulting to 0 if absent) parsed to zero or negative. Every healthy worker must advertise a positive concurrency capacity, so this value fails validation and the server is treated as unhealthy / the health refresh aborts. It indicates either a malformed/foreign health payload or a worker misconfiguration in versions that expose this as a setting.","triggerScenarios":"A worker whose /health omits max_concurrent_requests entirely (payload.get default 0) — e.g. an old-version worker or a mock; a misconfigured worker reporting 0 capacity; a hand-rolled service reusing the worker port; schema drift where the field was renamed between versions.","commonSituations":"Mock/test workers implementing only part of the health schema; version mismatches between router and worker; custom instrumentation accidentally overwriting the field.","solutions":["curl the worker's /health endpoint directly and check that max_concurrent_requests is present and > 0.","Align router and worker versions so the health schema matches (this error often co-occurs with the protocol_version check).","Configure the worker's concurrency setting properly for your hardware (it derives from worker capacity in shipped versions — do not force it to 0).","Fix test doubles to include all required health fields with realistic positive values."],"exampleFix":"# before (mock health)\n{'status': 'healthy', 'protocol_version': API_PROTOCOL_VERSION}  # missing field -> defaults to 0 -> ValueError\n\n# after\n{'status': 'healthy', 'protocol_version': API_PROTOCOL_VERSION, 'max_concurrent_requests': 4,\n 'queued_tasks': 0, 'processing_tasks': 0, 'completed_tasks': 0, 'failed_tasks': 0}","handlingStrategy":"validation","validationCode":"import httpx\n\ndef worker_health_is_valid(base_url: str) -> bool:\n    p = httpx.get(f'{base_url}/health', timeout=5).json()\n    return isinstance(p.get('max_concurrent_requests'), int) and p['max_concurrent_requests'] > 0","typeGuard":"def is_valid_health_payload(p: dict) -> bool:\n    return (\n        isinstance(p, dict)\n        and isinstance(p.get('max_concurrent_requests'), int)\n        and p['max_concurrent_requests'] > 0\n    )","tryCatchPattern":"try:\n    router._update_server_from_health_payload(server, payload)\nexcept ValueError as exc:\n    if 'max_concurrent_requests' in str(exc):\n        logger.error('worker %s reports invalid capacity — check version/schema of its health endpoint', server.base_url)\n    raise","preventionTips":["Mock and test health endpoints with complete, realistic payloads including a positive max_concurrent_requests.","Keep router and worker versions aligned so health schemas never drift.","Validate a worker's health payload once at enrollment, not only during periodic refresh."],"tags":["mineru","health-check","validation","worker-communication","schema"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}