ultralytics/yolov5 · error · RuntimeError

Expected {len(placeholders)} inputs, got {args_len}.

Error message

Expected {len(placeholders)} inputs, got {args_len}.

What it means

Raised by TritonClient._create_inputs (utils/triton.py) when positional args are used and their count does not equal the number of input placeholders the Triton model declares. Positional inputs are zipped 1:1 with the server's config, so the counts must match exactly (e.g. a single-'images' model requires exactly one tensor). Note the f-string was quoted in the source, so the message renders literally with '{len(placeholders)}' unexpanded.

Source

Thrown at utils/triton.py:71

        response = self.client.infer(model_name=self.model_name, inputs=inputs)
        result = []
        for output in self.metadata["outputs"]:
            tensor = torch.as_tensor(response.as_numpy(output["name"]))
            result.append(tensor)
        return result[0] if len(result) == 1 else result

    def _create_inputs(self, *args, **kwargs):
        """Creates input tensors from args or kwargs, not both; raises error if none or both are provided."""
        args_len, kwargs_len = len(args), len(kwargs)
        if not args_len and not kwargs_len:
            raise RuntimeError("No inputs provided.")
        if args_len and kwargs_len:
            raise RuntimeError("Cannot specify args and kwargs at the same time")

        placeholders = self._create_input_placeholders_fn()
        if args_len:
            if args_len != len(placeholders):
                raise RuntimeError(f"Expected {len(placeholders)} inputs, got {args_len}.")
            for input, value in zip(placeholders, args):
                input.set_data_from_numpy(value.cpu().numpy())
        else:
            for input in placeholders:
                value = kwargs[input.name]
                input.set_data_from_numpy(value.cpu().numpy())
        return placeholders

View on GitHub (pinned to 20d1d78a08)

Solutions

  1. Query the model's declared inputs and pass exactly that many positional tensors: print(client.metadata['inputs']) or check the model config on the Triton server.
  2. Unpack batch lists correctly: model(*batch) when batch is a list of input tensors, not model(batch).
  3. If the model genuinely has multiple inputs, prefer keyword form keyed by input name (model(images=img, metadata=meta)) to avoid ordering mistakes.
  4. Verify the deployed model version/config matches what the client code was written for.

Example fix

# before
outputs = model(img, img)  # model declares 1 input 'images'
# after
outputs = model(img)
Defensive patterns

Strategy: validation

Validate before calling

expected = len(client.metadata["inputs"])  # or from model config
if len(args) != expected:
    raise ValueError(
        f"Model declares {expected} inputs ({[i['name'] for i in client.metadata['inputs']]}); "
        f"got {len(args)} positional tensors."
    )
outputs = triton_model(*args)

Type guard

def matches_triton_input_count(args: tuple, input_names: list) -> bool:
    """True when positional tensor count equals the model's declared inputs."""
    return len(args) == len(input_names)

Try / catch

try:
    outputs = triton_model(*tensors)
except RuntimeError as e:
    if "inputs, got" in str(e):
        names = [i["name"] for i in client.metadata["inputs"]]
        raise ValueError(f"Pass exactly {len(names)} tensors, keyed by {names}") from e
    raise

Prevention

When it happens

Trigger: Calling a Triton-wrapped model with the wrong number of positional tensors: model(img, extra_tensor) for a model with one input, or model(img) for an ensemble model with two declared inputs. The placeholder list comes from the server's model config via _create_input_placeholders_fn().

Common situations: Ensemble or multi-input Triton models (image + metadata) invoked with only the image; a pipeline refactored from one input to several without updating the caller; passing a list as a single positional arg instead of unpacking (model(batch) vs model(*batch)); mismatch between the model version deployed on the server and the client's expectations.

Related errors


AI-assisted analysis of ultralytics/yolov5@20d1d78a08 (2026-08-15). Data as JSON: /api/errors/50d62f045db57797. Report an issue: GitHub.