Repository navigation
Description
Background
#776 added errorMessage to TaskStatusPollResponse, mapped from the error_message that Docling Serve returns on a failed task (see #775). Upstream TaskStatusResponse carries a second, richer failure field that we still don't map:
class TaskStatusResponse(BaseModel):
...
error_message: Optional[str] = None # mapped by #776
failure: Optional[PublicFailureInfo] = None # not mapped
class PublicFailureInfo(BaseModel):
category: FailureCategory
message: str
retryable: bool
phase: FailurePhase
details: dict[str, str] = Field(default_factory=dict)Why it is worth mapping
retryable is the main draw: it lets a caller decide whether to resubmit without parsing an error string. category and phase let a caller tell a bad input apart from a service outage.
failure.message is also more specific than error_message for the same failure. error_message is built by build_public_task_error, which returns the real exception text for only four exception types and otherwise returns the constant "Internal processing error.". For those same cases failure.message says things like "Task exceeded the allowed execution time." or "Source document could not be reached.".
Why it was left out of #776
- Ray only. Of the three orchestrators in
docling-jobkit, only the Ray dispatcher populatesfailure. The local orchestrator (whatDoclingServeContainerruns) and the RQ orchestrator seterror_messageonly. - v1.25.0+.
failurefirst appears in docling-serve v1.25.0, whereaserror_messageis returned by every tag in our compatibility table, back to v1.18.0.
error_message was therefore the right field for the bug fix. failure is additive value for Ray deployments.
Decision needed first: unknown enum values
Mapping failure means introducing FailureCategory (9 values today) and FailurePhase (4 values) into docling-serve-api.
We have no policy for unknown enum values anywhere in the repo — no READ_UNKNOWN_ENUM_VALUES_AS_NULL, no @JsonEnumDefaultValue. A constant added upstream would be a hard deserialization failure across the whole version range we test against.
TaskStatus gets away with this only because its value domain is genuinely frozen at four: the values actually assigned come from jobkit's own TaskStatus, not the wider ConversionStatus that the response model nominally declares. FailureCategory is documented upstream as shared across task and document scope and extensible, so it will grow.
Options:
- Map
category/phaseasString. No breakage risk, no type safety. - Map as enums with an
UNKNOWNconstant and@JsonEnumDefaultValue. Needs to hold for both the Jackson 2 and Jackson 3 mappers, including user-supplied ones. - Map as enums and set
READ_UNKNOWN_ENUM_VALUES_AS_NULLon both default mappers. Does not help a consumer who brings their own mapper.
Worth settling repo-wide rather than only for this field.
Scope
- Add
TaskFailureInfotoai.docling.serve.api.task.response, following the Lombok /@Jacksonized/ builder conventions already used byTaskStatusPollResponseandTaskStatusMetadata. - Add the
failurefield toTaskStatusPollResponse. - Resolve the enum question above.
- Do not change the
AsyncOperationsfailure message to preferfailure.message. It is Ray-only, soerror_messagestays the source for the message text;failureis data for callers.
Related drift
Two other places where our mirrors have fallen behind upstream, same root cause. Possibly worth folding in, possibly worth splitting out:
TaskStatusMetadatais missingnum_partially_succeeded(upstreamTaskProcessingMetahas five fields, we map four).ErrorItemis missingcategoryandpage_no.
Activity