opendataloader-project/opendataloader-pdf · error · IllegalStateException
Failed to convert via Hancom AI
Error message
Failed to convert via Hancom AI
What it means
convertAsync runs convert() on a CompletableFuture; checked IOException cannot propagate out of supplyAsync, so it is wrapped as IllegalStateException with the real IOException as cause. This is the Hancom AI equivalent of error 45 — the message is generic ('Failed to convert via Hancom AI') because the cause carries the actionable detail (DLA empty, pdf2img failure, etc.).
Source
Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/HancomAIClient.java:276
}
/**
* Creates a PageImageCache based on config.
*/
private PageImageCache createPageImageCache() throws IOException {
if ("disk".equalsIgnoreCase(config.getImageCache())) {
return new DiskPageImageCache();
}
return new MemoryPageImageCache();
}
@Override
public CompletableFuture<HybridResponse> convertAsync(HybridRequest request) {
return CompletableFuture.supplyAsync(() -> {
try {
return convert(request);
} catch (IOException e) {
throw new IllegalStateException("Failed to convert via Hancom AI", e);
}
});
}
/**
* Captions each Figure found by DLA:
* 1. Get page images via pdf2img
* 2. Find Figure objects (label 10) from DLA results
* 3. Crop each Figure from page image
* 4. Send cropped image to IMAGE_CAPTIONING
*
* @return ArrayNode of {page_number, object_id, bbox, caption}
*/
private ArrayNode captionFigures(byte[] pdfBytes, JsonNode dlaResult,
PageImageCache pageImageCache, CropOutput cropOutput) {
ArrayNode captions = objectMapper.createArrayNode();
// Extract pages from DLA resultView on GitHub (pinned to a7789b8e77)
Solutions
- Inspect the cause: ((IllegalStateException)e).getCause() for the real IOException
- Prefer synchronous convert() if you handle checked IOException directly
- Call checkAvailability() before convertAsync to fail fast
- Add retry with backoff for transient backend failures
Example fix
// before
HybridResponse r = client.convertAsync(req).join();
// after
HybridResponse r = client.convertAsync(req)
.exceptionally(e -> {
Throwable c = (e instanceof CompletionException && e.getCause() != null) ? e.getCause() : e;
throw new RuntimeException("hancom convert failed: " + c.getMessage(), c);
}).join(); Defensive patterns
Strategy: try-catch
Validate before calling
// Fail fast before the async call client.checkAvailability();
Try / catch
client.convertAsync(request)
.exceptionally(e -> {
Throwable cause = (e instanceof CompletionException && e.getCause() != null)
? e.getCause() : e;
// cause is the real IOException
log.error("Hancom convert failed: {}", cause.getMessage(), cause);
return null; // or trigger Java fallback
}); Prevention
- Always unwrap getCause() from convertAsync exceptions
- Prefer synchronous convert() to handle checked IOException directly
- Call checkAvailability() first for a precise failure reason
When it happens
Trigger: Calling HancomAIClient.convertAsync(request) and the underlying convert() throws IOException (DLA empty result, pdf2img HTTP error, page image fetch failure that escapes per-page handling, etc.).
Common situations: Using the async API and not inspecting getCause(); backend becoming unavailable mid-pipeline after the health check passed; a page-image failure that is not caught by the per-page handlers.
Related errors
- Failed to convert
- Failed to convert
- Option --%s: unsupported value '%s'. Supported values: %s, %
- Option --%s: unsupported value '%s'. Supported values: %s, %
- Option --%s: unsupported value '%s'. Supported values: memor
AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14).
Data as JSON: /api/errors/66919f32748b242d.
Report an issue: GitHub.