{"record":{"id":"cf52dcfcb221e0e0","repo":"opendatalab/MinerU","slug":"invalid-backend-allowed-values-allowed-values","errorCode":null,"errorMessage":"Invalid backend. Allowed values: {allowed_values}","messagePattern":"Invalid backend\\. Allowed values: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"mineru/cli/api_request.py","lineNumber":73,"sourceCode":"def validate_parse_method(parse_method: str) -> str:\n    \"\"\"校验公开 API 允许的 PDF 解析方式，避免各入口维护不同规则。\"\"\"\n    if parse_method not in ALLOWED_PARSE_METHODS:\n        raise HTTPException(\n            status_code=400,\n            detail=(\n                \"Invalid parse_method. Allowed values: \"\n                + \", \".join(sorted(ALLOWED_PARSE_METHODS))\n            ),\n        )\n    return parse_method\n\n\ndef validate_parse_backend(backend: str) -> str:\n    \"\"\"校验公开 API 允许的解析后端，避免旧入口名进入下游执行链路。\"\"\"\n    try:\n        return validate_public_backend(backend)\n    except ValueError as exc:\n        raise HTTPException(status_code=400, detail=str(exc)) from exc\n\n\ndef validate_parse_effort(effort: str) -> str:\n    \"\"\"校验公开 API 允许的 hybrid effort，避免非法值进入解析链路。\"\"\"\n    try:\n        return validate_public_effort(effort)\n    except ValueError as exc:\n        raise HTTPException(status_code=400, detail=str(exc)) from exc\n\n\ndef validate_parse_lang_list(lang_list: list[str]) -> list[str]:\n    \"\"\"校验公开 API 允许的 OCR 语言列表，避免旧语言入口进入解析链路。\"\"\"\n    try:\n        return validate_public_ocr_lang_list(lang_list)\n    except ValueError as exc:\n        raise HTTPException(status_code=400, detail=str(exc)) from exc\n\n","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/cli/api_request.py#L55-L91","documentation":"HTTP 400 raised by validate_parse_backend() on the API server: the backend form value is normalized through validate_public_backend (LEGACY_BACKEND_ALIASES applied) and must end up in PUBLIC_BACKEND_CHOICES = (pipeline, vlm-engine, hybrid-engine, vlm-http-client, hybrid-http-client). This mirrors the CLI-side check in backend_options.py so no legacy backend name reaches the execution chain.","triggerScenarios":"POSTing a parse request with backend='vlm', 'hybrid', 'vlm-auto-engine' (actually aliased and OK), 'torch', or any string not in the five public choices.","commonSituations":"Older mineru releases used short names like 'vlm'/'pipeline-backend'; users mixing up parse_method and backend values; renamed constants after upgrades (e.g. vlm-auto-engine -> vlm-engine, which the alias map still accepts).","solutions":["Use one of: pipeline, vlm-engine, hybrid-engine, vlm-http-client, hybrid-http-client","Legacy aliases vlm-auto-engine and hybrid-auto-engine are still accepted — but migrate to the new names","Do not put parse_method values (auto/txt/ocr) into the backend field","Verify against the server's /docs schema enum"],"exampleFix":"# before\nrequests.post(url, files=files, data={'backend': 'vlm'})\n\n# after\nrequests.post(url, files=files, data={'backend': 'vlm-engine'})","handlingStrategy":"validation","validationCode":"from mineru.cli.backend_options import PUBLIC_BACKEND_CHOICES, validate_backend\n\nbackend = validate_backend(backend)  # raises ValueError with the allowed list","typeGuard":"from mineru.cli.backend_options import PUBLIC_BACKEND_CHOICES\n\ndef is_valid_backend(v: str) -> bool:\n    return isinstance(v, str) and (v in PUBLIC_BACKEND_CHOICES or v in {\n        \"vlm-auto-engine\", \"hybrid-auto-engine\",\n    })","tryCatchPattern":"try:\n    resp = requests.post(url, files=files, data={\"backend\": backend}, timeout=60)\n    resp.raise_for_status()\nexcept requests.HTTPError as e:\n    if e.response.status_code == 400 and \"backend\" in e.response.text:\n        backend = \"hybrid-engine\"  # safe default; retry once\n    else:\n        raise","preventionTips":["Call validate_backend() client-side before sending the request","Migrate off legacy aliases even though they still resolve","Log the server's allowed-values string from the 400 body — it is authoritative for that version"],"tags":["api","http-400","validation","backend"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}