docling-project/docling · error · ValueError

Unsupported KServe request parameter type for gRPC: key={key

Error message

Unsupported KServe request parameter type for gRPC: key={key}, type={type(value)}. Supported: bool, int, float, str.

What it means

Raised as ValueError by _set_request_parameter when a request parameter value has a type the KServe gRPC protobuf schema cannot represent. Only bool, int (incl. numpy integers), float (incl. numpy floats), and str are accepted; note bool is checked first because bool is a subclass of int in Python.

Source

Thrown at docling/models/inference_engines/common/kserve_v2_grpc.py:105

            parameter.int64_param = int_value
            return
        if int_value <= (2**63 - 1):
            parameter.int64_param = int_value
            return
        if int_value <= (2**64 - 1):
            parameter.uint64_param = int_value
            return
        raise ValueError(
            "Unsupported KServe request parameter integer range for gRPC: "
            f"key={key}, value={int_value}"
        )
    if isinstance(value, float | np.floating):
        parameter.double_param = float(value)
        return
    if isinstance(value, str):
        parameter.string_param = value
        return
    raise ValueError(
        "Unsupported KServe request parameter type for gRPC: "
        f"key={key}, type={type(value)}. Supported: bool, int, float, str."
    )


def _encode_contents(tensor: np.ndarray, contents: Any) -> None:
    """Populate an InferTensorContents message from a numpy array (non-binary path)."""
    flat = tensor.flatten()
    if tensor.dtype == np.float32:
        contents.fp32_contents.extend(flat.tolist())
    elif tensor.dtype == np.float64:
        contents.fp64_contents.extend(flat.tolist())
    elif tensor.dtype in (np.int8, np.int16, np.int32):
        contents.int_contents.extend(flat.astype(np.int32).tolist())
    elif tensor.dtype == np.int64:
        contents.int64_contents.extend(flat.tolist())
    elif tensor.dtype in (np.uint8, np.uint16, np.uint32):
        contents.uint_contents.extend(flat.astype(np.uint32).tolist())

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Flatten/serialize non-primitive values: json.dumps for lists/dicts, drop None entries.
  2. Filter the parameters mapping to bool/int/float/str before the call.
  3. If you need structured parameters, encode them as a JSON string parameter.

Example fix

# before
params = {'thresholds': [0.1, 0.5], 'note': None}  # list/None -> ValueError

# after
import json
params = {'thresholds': json.dumps([0.1, 0.5])}
params = {k: v for k, v in params.items() if v is not None}
Defensive patterns

Strategy: validation

Validate before calling

import json
allowed = (bool, int, float, str)
clean = {}
for k, v in params.items():
    if v is None:
        continue
    clean[k] = json.dumps(v) if isinstance(v, (list, dict)) else v

Type guard

def is_grpc_param(v) -> bool:
    return isinstance(v, (bool, int, float, str)) and not isinstance(v, bool) or isinstance(v, bool)

Prevention

When it happens

Trigger: Passing None, list, dict, tuple, bytes, or any custom object as a value in the parameters mapping of a KServe gRPC inference request.

Common situations: Forwarding an unfiltered config dict (which contains nested structures) as request parameters; optional parameters left as None; json-serialized values that arrive as lists.

Related errors


AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14). Data as JSON: /api/errors/d14c3b84ceb6dd7d. Report an issue: GitHub.