{"record":{"id":"475103337dd697a3","repo":"langchain-ai/langchain","slug":"length-must-be-0-but-got-length","errorCode":null,"errorMessage":"length must be >= 0, but got {length}","messagePattern":"length must be >= 0, but got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/runnables/config.py","lineNumber":331,"sourceCode":") -> list[RunnableConfig]:\n    \"\"\"Get a list of configs from a single config or a list of configs.\n\n     It is useful for subclasses overriding batch() or abatch().\n\n    Args:\n        config: The config or list of configs.\n        length: The length of the list.\n\n    Returns:\n        The list of configs.\n\n    Raises:\n        ValueError: If the length of the list is not equal to the length of the inputs.\n\n    \"\"\"\n    if length < 0:\n        msg = f\"length must be >= 0, but got {length}\"\n        raise ValueError(msg)\n    if isinstance(config, Sequence) and len(config) != length:\n        msg = (\n            f\"config must be a list of the same length as inputs, \"\n            f\"but got {len(config)} configs for {length} inputs\"\n        )\n        raise ValueError(msg)\n\n    if isinstance(config, Sequence):\n        return list(map(ensure_config, config))\n    if length > 1 and isinstance(config, dict) and config.get(\"run_id\") is not None:\n        warnings.warn(\n            \"Provided run_id be used only for the first element of the batch.\",\n            category=RuntimeWarning,\n            stacklevel=3,\n        )\n        subsequent = cast(\n            \"RunnableConfig\", {k: v for k, v in config.items() if k != \"run_id\"}\n        )","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/runnables/config.py#L313-L349","documentation":"`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)`.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the length computation in the calling code — it should be `len(inputs)` (or the size of the sublist actually being processed).","Return early for empty inputs before calling `get_config_list` so subtraction-based lengths never go negative.","Add an assertion/log of the computed length in custom batch overrides while developing."],"exampleFix":"# before\ndef batch(self, inputs, config=None, **kwargs):\n    n = len(inputs) - 1  # -1 when inputs is empty\n    configs = get_config_list(config, n)\n\n# after\ndef batch(self, inputs, config=None, **kwargs):\n    configs = get_config_list(config, len(inputs))","handlingStrategy":"validation","validationCode":"assert length >= 0, f\"invalid length {length}\"\nconfigs = get_config_list(config, length)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In custom batch overrides, pass len(inputs) directly instead of computed arithmetic.","Return early on empty input lists before computing config counts.","Never subtract from lengths that can be zero."],"tags":["config","batch","value-error","internal-api","langchain-core"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}