opendataloader-project/opendataloader-pdf · error · IllegalArgumentException

Unknown hybrid backend: %s. Supported backends: %s

Error message

Unknown hybrid backend: %s. Supported backends: %s

What it means

The backend type string passed to the factory does not match any known constant (docling-fast, hancom, hancom-ai, azure, google). This includes typos, case issues (though getOrCreate lowercases the input first), and entirely unrecognized names. The error message lists all supported backends via getSupportedBackends() for immediate guidance. Unlike azure/google (which throw UnsupportedOperationException), this is an IllegalArgumentException — the input is fundamentally wrong, not just unimplemented.

Source

Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/HybridClientFactory.java:104

        return CLIENT_CACHE.computeIfAbsent(lowerHybrid, key -> createClient(key, config));
    }

    /**
     * Creates a new hybrid client instance.
     */
    private static HybridClient createClient(String hybrid, HybridConfig config) {
        if (BACKEND_DOCLING_FAST.equals(hybrid)) {
            return new DoclingFastServerClient(config);
        } else if (BACKEND_HANCOM.equals(hybrid)) {
            return new HancomClient(config);
        } else if (BACKEND_HANCOM_AI.equals(hybrid)) {
            return new HancomAIClient(config);
        } else if (BACKEND_AZURE.equals(hybrid)) {
            throw new UnsupportedOperationException("Azure Document Intelligence backend is not yet implemented");
        } else if (BACKEND_GOOGLE.equals(hybrid)) {
            throw new UnsupportedOperationException("Google Document AI backend is not yet implemented");
        } else {
            throw new IllegalArgumentException("Unknown hybrid backend: " + hybrid +
                ". Supported backends: " + getSupportedBackends());
        }
    }

    /**
     * Creates a hybrid client for the specified backend.
     *
     * @param hybrid The backend type (e.g., "docling", "hancom", "azure", "google").
     * @param config The configuration for the hybrid client.
     * @return A new HybridClient instance for the specified backend.
     * @throws IllegalArgumentException If the backend type is unknown or not supported.
     * @deprecated Use {@link #getOrCreate(String, HybridConfig)} instead to reuse clients.
     */
    @Deprecated
    public static HybridClient create(String hybrid, HybridConfig config) {
        return getOrCreate(hybrid, config);
    }

View on GitHub (pinned to a7789b8e77)

Solutions

  1. Check the error message — it lists all supported backends. Use one of those exact strings.
  2. For docling: the correct value is 'docling-fast', not 'docling'.
  3. For Hancom: use 'hancom' (standard API) or 'hancom-ai' (HOCR SDK), not 'hancom_ai' or 'HancomAI'.
  4. Trim whitespace from config file values before passing to the factory.
  5. Use the public constants: HybridClientFactory.BACKEND_HANCOM, BACKEND_DOCLING_FAST, etc.

Example fix

// before: typo in backend name
HybridClient client = HybridClientFactory.getOrCreate("hanocom", config);

// after: use the correct constant
HybridClient client = HybridClientFactory.getOrCreate(
    HybridClientFactory.BACKEND_HANCOM, config);
Defensive patterns

Strategy: validation

Validate before calling

Set<String> validBackends = Set.of(
    HybridClientFactory.BACKEND_DOCLING_FAST,
    HybridClientFactory.BACKEND_HANCOM,
    HybridClientFactory.BACKEND_HANCOM_AI,
    HybridClientFactory.BACKEND_AZURE, // throws UnsupportedOperationException
    HybridClientFactory.BACKEND_GOOGLE  // throws UnsupportedOperationException
);
String normalized = backend.trim().toLowerCase();
if (!validBackends.contains(normalized)) {
    throw new IllegalArgumentException(
        "Unknown backend '" + backend + "'. Valid: " + HybridClientFactory.getSupportedBackends());
}

Type guard

public static boolean isKnownBackend(String backend) {
    if (backend == null) return false;
    String lower = backend.toLowerCase();
    return HybridClientFactory.BACKEND_DOCLING_FAST.equals(lower)
        || HybridClientFactory.BACKEND_HANCOM.equals(lower)
        || HybridClientFactory.BACKEND_HANCOM_AI.equals(lower)
        || HybridClientFactory.BACKEND_AZURE.equals(lower)
        || HybridClientFactory.BACKEND_GOOGLE.equals(lower);
}

Try / catch

try {
    client = HybridClientFactory.getOrCreate(backend, config);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Unknown hybrid backend")) {
        // Typo or unsupported — show valid options to the user
        System.err.println("Error: " + e.getMessage());
        System.err.println("Supported: " + HybridClientFactory.getSupportedBackends());
        System.exit(1);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling HybridClientFactory.getOrCreate() with a typo like 'hanocom', 'docling' (instead of 'docling-fast'), 'Hancom' (handled by toLowerCase but worth noting), or any completely unrelated string. Also triggered by passing 'docling' when the correct constant is 'docling-fast'.

Common situations: CLI typo: `--hybrid hancom` vs `--hybrid hanocom`; using 'docling' instead of 'docling-fast'; truncation or whitespace in a config file value; copy-paste from outdated documentation that used different backend names.

Related errors


AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14). Data as JSON: /api/errors/83fd96891f9f5fe4. Report an issue: GitHub.