langchain-ai/langchain · error · ValueError

length must be >= 0, but got {length}

Error message

length must be >= 0, but got {length}

What it means

`get_config_list` in `langchain_core.runnables.config` validates that the `length` argument (the number of batch inputs) is non-negative before building per-input configs. A negative length means the caller passed an invalid input count, which is almost always an internal-programming error in a custom `Runnable` subclass, since standard batch methods derive length from `len(inputs)`.

Source

Thrown at libs/core/langchain_core/runnables/config.py:331

) -> list[RunnableConfig]:
    """Get a list of configs from a single config or a list of configs.

     It is useful for subclasses overriding batch() or abatch().

    Args:
        config: The config or list of configs.
        length: The length of the list.

    Returns:
        The list of configs.

    Raises:
        ValueError: If the length of the list is not equal to the length of the inputs.

    """
    if length < 0:
        msg = f"length must be >= 0, but got {length}"
        raise ValueError(msg)
    if isinstance(config, Sequence) and len(config) != length:
        msg = (
            f"config must be a list of the same length as inputs, "
            f"but got {len(config)} configs for {length} inputs"
        )
        raise ValueError(msg)

    if isinstance(config, Sequence):
        return list(map(ensure_config, config))
    if length > 1 and isinstance(config, dict) and config.get("run_id") is not None:
        warnings.warn(
            "Provided run_id be used only for the first element of the batch.",
            category=RuntimeWarning,
            stacklevel=3,
        )
        subsequent = cast(
            "RunnableConfig", {k: v for k, v in config.items() if k != "run_id"}
        )

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Fix the length computation in the calling code — it should be `len(inputs)` (or the size of the sublist actually being processed).
  2. Return early for empty inputs before calling `get_config_list` so subtraction-based lengths never go negative.
  3. Add an assertion/log of the computed length in custom batch overrides while developing.

Example fix

# before
def batch(self, inputs, config=None, **kwargs):
    n = len(inputs) - 1  # -1 when inputs is empty
    configs = get_config_list(config, n)

# after
def batch(self, inputs, config=None, **kwargs):
    configs = get_config_list(config, len(inputs))
Defensive patterns

Strategy: validation

Validate before calling

assert length >= 0, f"invalid length {length}"
configs = get_config_list(config, length)

Prevention

When it happens

Trigger: A custom `Runnable.batch()`/`abatch()` override calling `get_config_list(config, -1)` or with a computed length that can go negative (e.g. `len(inputs) - 1` when `inputs` is empty). Not reachable through normal `invoke`/`batch` calls on built-in runnables.

Common situations: Off-by-one arithmetic in a subclassed batch method; slicing logic like `inputs[offset - 1:]` producing a negative count; passing `-len(batch)` by sign mistake in sharding code.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/475103337dd697a3. Report an issue: GitHub.