PaddlePaddle/PaddleOCR · error · TypeError

The input data is inconsistent with expectations.

Error message

The input data is inconsistent with expectations.

What it means

Raised by the structure_layout hubserving module's predict method when input validation fails. The module needs exactly one non-empty list — `images` (numpy arrays) or `paths` (file path strings); the if/elif chain rejects every other shape with this TypeError.

Source

Thrown at deploy/hubserving/structure_layout/module.py:111

            images.append(img)
        return images

    def predict(self, images=[], paths=[]):
        """
        Get the chinese texts in the predicted images.
        Args:
            images (list(numpy.ndarray)): images data, shape of each is [H, W, C]. If images not paths
            paths (list[str]): The paths of images. If paths not images
        Returns:
            res (list): The layout results of images.
        """

        if images != [] and isinstance(images, list) and paths == []:
            predicted_data = images
        elif images == [] and isinstance(paths, list) and paths != []:
            predicted_data = self.read_images(paths)
        else:
            raise TypeError("The input data is inconsistent with expectations.")

        assert (
            predicted_data != []
        ), "There is not any image to be predicted. Please check the input data."

        all_results = []
        for img in predicted_data:
            if img is None:
                logger.info("error in loading image")
                all_results.append([])
                continue
            starttime = time.time()
            res, _ = self.layout_predictor(img)
            elapse = time.time() - starttime
            logger.info("Predict time: {}".format(elapse))

            for item in res:
                item["bbox"] = item["bbox"].tolist()

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Send exactly one non-empty array: {"images": [...]} or {"paths": [...]}.
  2. Remove the unused key from the JSON body entirely.
  3. For direct calls, pass predict(images=[...], paths=[]) or the mirror form.

Example fix

# before
res = mod.predict(images=[], paths="page-3.png")  # string -> TypeError

# after
res = mod.predict(images=[], paths=["page-3.png"])
Defensive patterns

Strategy: validation

Validate before calling

def valid_layout_payload(data: dict) -> bool:
    imgs, paths = data.get("images"), data.get("paths")
    return (isinstance(imgs, list) and imgs and not paths) or (
        isinstance(paths, list) and paths and not imgs
    )

Type guard

def is_nonempty_str_list(v) -> bool:
    return isinstance(v, list) and len(v) > 0 and all(isinstance(s, str) for s in v)

Try / catch

try:
    res = mod.predict(images=images, paths=paths)
except TypeError as e:
    if "inconsistent" in str(e):
        return {"error": "exactly one of images[]/paths[] required"}, 400
    raise

Prevention

When it happens

Trigger: predict called with both fields set, both empty, or a non-list value (bare string path, single ndarray) for either argument.

Common situations: Layout-analysis requests that mirror a different module's payload format; clients that always include both keys with defaults; feeding PDF page images without wrapping them in a list.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/d40c11256ae140ef. Report an issue: GitHub.