{"record":{"id":"800eed7813583650","repo":"langchain-ai/langchain","slug":"callbacks-must-be-the-same-length-as-prompts","errorCode":null,"errorMessage":"callbacks must be the same length as prompts","messagePattern":"callbacks must be the same length as prompts","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/language_models/llms.py","lineNumber":939,"sourceCode":"                for meta in metadata\n            ]\n        elif isinstance(metadata, dict):\n            metadata = {\n                **(metadata or {}),\n                **self._get_ls_params_with_defaults(stop=stop, **kwargs),\n            }\n        if (\n            isinstance(callbacks, list)\n            and callbacks\n            and (\n                isinstance(callbacks[0], (list, BaseCallbackManager))\n                or callbacks[0] is None\n            )\n        ):\n            # We've received a list of callbacks args to apply to each input\n            if len(callbacks) != len(prompts):\n                msg = \"callbacks must be the same length as prompts\"\n                raise ValueError(msg)\n            if tags is not None and not (\n                isinstance(tags, list) and len(tags) == len(prompts)\n            ):\n                msg = \"tags must be a list of the same length as prompts\"\n                raise ValueError(msg)\n            if metadata is not None and not (\n                isinstance(metadata, list) and len(metadata) == len(prompts)\n            ):\n                msg = \"metadata must be a list of the same length as prompts\"\n                raise ValueError(msg)\n            if run_name is not None and not (\n                isinstance(run_name, list) and len(run_name) == len(prompts)\n            ):\n                msg = \"run_name must be a list of the same length as prompts\"\n                raise ValueError(msg)\n            tags_list = cast(\"list[list[str] | None]\", tags or ([None] * len(prompts)))\n            metadata_list = cast(\n                \"list[builtins.dict[str, Any] | None]\",","sourceCodeStart":921,"sourceCodeEnd":957,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/language_models/llms.py#L921-L957","documentation":"`ValueError` from `BaseLLM.generate`: per-input callbacks were supplied as a list of callback args (a list whose first element is itself a list, a `BaseCallbackManager`, or `None`), which switches the API into per-prompt mode — and that list's length must equal `len(prompts)`. A mismatch means some prompts would silently get no handlers.","triggerScenarios":"Calling `llm.generate(prompts, callbacks=[handler_a, handler_b])` where `handler_a` is itself a list/manager (or `None`) — interpreted as per-prompt callbacks — with a different count than prompts. E.g. `generate([p1, p2, p3], callbacks=[[cb1], [cb2]])`.","commonSituations":"Mixing up the two `callbacks` shapes (flat handler list vs. nested per-prompt list); passing `callbacks=[None, handler]` for two of five prompts; dynamically building per-prompt handler lists that drift out of sync with prompt filtering.","solutions":["For one handler set across all prompts, pass it flat: `callbacks=handler` or `callbacks=[handler]` where the handler is not itself a list.","For per-prompt callbacks, build exactly one entry per prompt: `[handlers[i] for i in range(len(prompts))]`.","Zip-derive both from the same source list so they cannot diverge.","Validate lengths before the call in your own wrapper."],"exampleFix":"# before\nllm.generate([p1, p2, p3], callbacks=[[cb1], [cb2]])  # 3 prompts, 2 entries\n\n# after\nllm.generate([p1, p2, p3], callbacks=[[cb1], [cb2], [cb3]])\n# or, same handlers for all:\nllm.generate([p1, p2, p3], callbacks=cb1)","handlingStrategy":"validation","validationCode":"per_prompt = (\n    isinstance(callbacks, list)\n    and callbacks\n    and (isinstance(callbacks[0], (list, BaseCallbackManager)) or callbacks[0] is None)\n)\nif per_prompt and len(callbacks) != len(prompts):\n    callbacks = callbacks + [None] * (len(prompts) - len(callbacks))  # or raise","typeGuard":"from langchain_core.callbacks import BaseCallbackManager\ndef is_per_prompt_callbacks(callbacks: object) -> bool:\n    return (\n        isinstance(callbacks, list)\n        and bool(callbacks)\n        and (isinstance(callbacks[0], (list, BaseCallbackManager)) or callbacks[0] is None)\n    )","tryCatchPattern":"try:\n    result = llm.generate(prompts, callbacks=callbacks)\nexcept ValueError as e:\n    if \"same length as prompts\" in str(e):\n        raise ValueError(f\"align callbacks ({len(callbacks)}) with prompts ({len(prompts)})\") from e\n    raise","preventionTips":["Pass a single flat handler (not nested) when all prompts share handlers.","Build per-prompt callback lists with a comprehension over the prompts list itself.","Validate lengths of `callbacks`/`tags`/`metadata`/`run_name` together in wrappers."],"tags":["callbacks","input-validation","batch","length-mismatch"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}