docling-project/docling · error · ValueError
submit_batch() requires either 'target' or 'targets'.
Error message
submit_batch() requires either 'target' or 'targets'.
What it means
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.
Source
Thrown at docling/service_client/_async_client.py:314
initial_status=initial_status,
)
async def submit_batch(
self,
sources: Sequence[BatchSourceRequestInput],
target: BatchTargetRequestInput | None = None,
output_formats: list[OutputFormat] | None = None,
options: ConvertDocumentsRequestOptions | None = None,
headers: dict[str, str] | None = None,
*,
targets: list[BatchTargetRequestInput] | None = None,
) -> (
AsyncConversionJob[PresignedUrlConvertDocumentResponse]
| AsyncConversionJob[PresignedUrlConvertResponse]
):
assert self._async_client is not None, "client not open — use async with"
if target is None and targets is None:
raise ValueError("submit_batch() requires either 'target' or 'targets'.")
if target is not None and targets is not None:
raise ValueError(
"submit_batch() received both 'target' and 'targets'; supply only one."
)
payload: dict[str, Any] = {"sources": sources}
if targets is not None:
payload["targets"] = targets
else:
payload["target"] = target
request = BatchConvertSourcesRequest.model_validate(payload)
resolved = self._resolve_options(
options=options,
max_num_pages=None,
max_file_size=None,
page_range=None,
)
# Use the first effective target for output-format hint.
first_target = (request.targets or [request.target])[0]View on GitHub (pinned to 61d76f1ff3)
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.).
Example fix
# before
job = await client.submit_batch(sources=sources) # no target
# after
from docling.service_client.datatypes import BatchTargetRequestInput, OutputFormat
job = await client.submit_batch(
sources=sources,
target=BatchTargetRequestInput(to_formats=[OutputFormat.MD]),
) Defensive patterns
Strategy: validation
Validate before calling
if target is None and not targets:
raise ValueError('configure at least one conversion target before submit_batch') Prevention
- Always pass target= or targets= explicitly to submit_batch.
- In wrappers, assert the target argument is populated before forwarding.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- submit_batch() received both 'target' and 'targets'; supply
- Response schema mismatch — client and server versions may di
- Unsupported URL scheme: '{scheme}'. Only http:// and https:/
- {name} must be between 1 and {MAX_CONCURRENCY_LIMIT}, got {v
- Cannot convert Box Note with hash {self.document_hash}: no '
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/65333f7d11fb17cd.
Report an issue: GitHub.