{"record":{"id":"9303a6bd345dee90","repo":"BerriAI/litellm","slug":"target-model-names-is-required-for-this-routing-sc","errorCode":null,"errorMessage":"target_model_names is required for this routing scenario","messagePattern":"target_model_names is required for this routing scenario","errorType":"exception","errorClass":"ValueError","httpStatus":500,"severity":"error","filePath":"litellm/proxy/batches_endpoints/endpoints.py","lineNumber":792,"sourceCode":"                after=after,\n                limit=limit,\n                **data,\n            )\n\n            # Encode batch IDs in the list response so clients can use\n            # them for retrieve/cancel/file downloads through the proxy.\n            response_data: Final = getattr(response, \"data\", None)\n            if response_data:\n                for batch in response_data:\n                    encode_batch_response_ids(batch, model=model_param)\n\n            verbose_proxy_logger.debug(\"Listed batches using model: %s\", model_param)\n\n        # SCENARIO 2 (alternative): target_model_names based routing\n        elif target_model_names or data.get(\"target_model_names\", None):\n            target_model_names = target_model_names or data.get(\"target_model_names\", None)\n            if target_model_names is None:\n                raise ValueError(\"target_model_names is required for this routing scenario\")\n            model: Final = target_model_names.split(\",\")[0]\n            data.pop(\"model\", None)\n            response = await llm_router.alist_batches(\n                model=model,\n                after=after,\n                limit=limit,\n                **data,\n            )\n\n        # SCENARIO 3: Fallback to custom_llm_provider (uses env variables)\n        else:\n            custom_llm_provider: Final = (\n                provider\n                or get_custom_llm_provider_from_request_headers(request=request)\n                or get_custom_llm_provider_from_request_query(request=request)\n                or \"openai\"\n            )\n            apply_team_provider_credentials(","sourceCodeStart":774,"sourceCodeEnd":810,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/batches_endpoints/endpoints.py#L774-L810","documentation":"In GET /v1/batches, SCENARIO 2 handles target_model_names routing (query param or JSON body). The code re-assigns target_model_names from whichever source is set, then raises ValueError('target_model_names is required for this routing scenario') if it is still None. Because the enclosing elif only runs when one of the two sources is truthy, this is a defensive invariant check whose failure branch normal requests cannot reach; if it fires, the ValueError escapes as an unhandled server error (HTTP 500), signalling a code regression or mutated request state rather than bad caller input.","triggerScenarios":"Not reachable through well-formed requests - the elif condition guarantees a non-None value; it would require the request-body dict to change between check and assignment, or a modified/older build of this routing code.","commonSituations":"Encountered only as an unexpected 500 whose traceback contains this ValueError, usually on patched or older LiteLLM versions where the branch structure differs.","solutions":["Upgrade to the latest litellm; this guard path may have been reworked.","Capture the traceback plus the exact request (query string and body) and open an issue at github.com/BerriAI/litellm.","Workaround: send target_model_names as a query parameter only, avoiding duplicate body keys."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    page = client.batches.list(extra_query={'target_model_names': name})\nexcept openai.InternalServerError as e:\n    if 'target_model_names is required for this routing scenario' in str(e):\n        # proxy-side invariant trip - not an input problem; do not retry blindly\n        capture_request_for_bug_report()\n        raise","preventionTips":["Pass target_model_names as a single query parameter instead of duplicating it in the JSON body.","Keep litellm versions uniform across environments.","Report reproducible occurrences with the full traceback to the litellm maintainers."],"tags":["litellm-proxy","batches","internal-error","invariant-check","http-500"],"backgroundTag":"internal-invariant-violation","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}