{"record":{"id":"65333f7d11fb17cd","repo":"docling-project/docling","slug":"submit-batch-requires-either-target-or-target","errorCode":null,"errorMessage":"submit_batch() requires either 'target' or 'targets'.","messagePattern":"submit_batch\\(\\) requires either 'target' or 'targets'\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"docling/service_client/_async_client.py","lineNumber":314,"sourceCode":"            initial_status=initial_status,\n        )\n\n    async def submit_batch(\n        self,\n        sources: Sequence[BatchSourceRequestInput],\n        target: BatchTargetRequestInput | None = None,\n        output_formats: list[OutputFormat] | None = None,\n        options: ConvertDocumentsRequestOptions | None = None,\n        headers: dict[str, str] | None = None,\n        *,\n        targets: list[BatchTargetRequestInput] | None = None,\n    ) -> (\n        AsyncConversionJob[PresignedUrlConvertDocumentResponse]\n        | AsyncConversionJob[PresignedUrlConvertResponse]\n    ):\n        assert self._async_client is not None, \"client not open — use async with\"\n        if target is None and targets is None:\n            raise ValueError(\"submit_batch() requires either 'target' or 'targets'.\")\n        if target is not None and targets is not None:\n            raise ValueError(\n                \"submit_batch() received both 'target' and 'targets'; supply only one.\"\n            )\n        payload: dict[str, Any] = {\"sources\": sources}\n        if targets is not None:\n            payload[\"targets\"] = targets\n        else:\n            payload[\"target\"] = target\n        request = BatchConvertSourcesRequest.model_validate(payload)\n        resolved = self._resolve_options(\n            options=options,\n            max_num_pages=None,\n            max_file_size=None,\n            page_range=None,\n        )\n        # Use the first effective target for output-format hint.\n        first_target = (request.targets or [request.target])[0]","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/service_client/_async_client.py#L296-L332","documentation":"The async service client's submit_batch() builds a batch payload containing either a single 'target' or a list 'targets'. Both parameters are optional, but supplying neither leaves the request with no conversion target, which cannot form a valid BatchConvertSourcesRequest, so the client raises ValueError immediately instead of sending a malformed request.","triggerScenarios":"Calling submit_batch(sources=...) with both target=None and targets=None, e.g. relying on a default target that does not exist; refactoring call sites where the target argument was dropped; conditionally building targets and passing an empty/falsy expression that evaluates to None.","commonSituations":"Copy-pasting a submit_batch call and deleting the target line; looping over configurations where some iterations intentionally have no target; new users assuming the service applies a server-side default target.","solutions":["Pass target=BatchTargetRequestInput(...) (single) or targets=[...] (list) explicitly to submit_batch.","If constructing targets dynamically, guard the call so it only fires when at least one target exists.","Check the async client docs/signature to see the expected BatchTargetRequestInput shape (to_formats, image_export, etc.)."],"exampleFix":"# before\njob = await client.submit_batch(sources=sources)  # no target\n\n# after\nfrom docling.service_client.datatypes import BatchTargetRequestInput, OutputFormat\njob = await client.submit_batch(\n    sources=sources,\n    target=BatchTargetRequestInput(to_formats=[OutputFormat.MD]),\n)","handlingStrategy":"validation","validationCode":"if target is None and not targets:\n    raise ValueError('configure at least one conversion target before submit_batch')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass target= or targets= explicitly to submit_batch.","In wrappers, assert the target argument is populated before forwarding."],"tags":["service-client","async","validation","batch"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}