{"record":{"id":"87e2cc8691a2284f","repo":"langchain-ai/langchain","slug":"metadata-must-be-a-list-of-the-same-length-as-prom","errorCode":null,"errorMessage":"metadata must be a list of the same length as prompts","messagePattern":"metadata must be a list of the same length as prompts","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/language_models/llms.py","lineNumber":949,"sourceCode":"            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]\",\n                metadata or ([{}] * len(prompts)),\n            )\n            run_name_list = run_name or cast(\n                \"list[str | None]\", ([None] * len(prompts))\n            )\n            params = self._dict_for_compat()\n            params[\"stop\"] = stop\n            callback_managers = [\n                CallbackManager.configure(\n                    callback,","sourceCodeStart":931,"sourceCodeEnd":967,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/language_models/llms.py#L931-L967","documentation":"Raised by BaseLLM.generate during batch generation with per-prompt callbacks. If metadata is provided alongside a per-prompt callbacks list, metadata must be a list of dicts with one dict per prompt. A single dict or a mismatched-length list is rejected.","triggerScenarios":"Calling llm.generate(prompts, callbacks=[[cb], [cb]], metadata={'user': 'a'}) — a single dict instead of a list of dicts; or metadata=[{'user': 'a'}] with 2+ prompts. Only checked when callbacks[0] is a list/BaseCallbackManager/None.","commonSituations":"Copying a metadata dict used with single-prompt invoke into a batched generate call; LangSmith tracing setups that attach metadata per run and forget to fan it out per prompt.","solutions":["Pass metadata as a list of dicts of length len(prompts): metadata=[md] * len(prompts)","Or omit metadata (pass None) if per-prompt metadata is not needed","Verify len(callbacks) == len(prompts) first, since the metadata check only runs in that branch"],"exampleFix":"# before\nllm.generate(prompts, callbacks=per_prompt_cbs, metadata={'run': 'x'})\n# after\nllm.generate(prompts, callbacks=per_prompt_cbs, metadata=[{'run': 'x'}] * len(prompts))","handlingStrategy":"validation","validationCode":"n = len(prompts)\nif metadata is not None:\n    assert isinstance(metadata, list) and len(metadata) == n, f'metadata must be a list of {n} dicts'","typeGuard":"def valid_batch_metadata(md: object, n: int) -> bool:\n    return md is None or (isinstance(md, list) and len(md) == n and all(isinstance(d, dict) for d in md))","tryCatchPattern":"try:\n    llm.generate(prompts, callbacks=cbs, metadata=metadata)\nexcept ValueError as e:\n    if 'metadata must be a list' in str(e) and isinstance(metadata, dict):\n        llm.generate(prompts, callbacks=cbs, metadata=[metadata] * len(prompts))\n    else:\n        raise","preventionTips":["Never pass a bare dict as metadata to a batched call with per-prompt callbacks","Use [md] * len(prompts) to fan out shared metadata","Log len() of every per-prompt argument before dispatch in batch pipelines"],"tags":["llm","batch","metadata","validation"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}