{"record":{"id":"0fa4229c656e8735","repo":"langchain-ai/langchain","slug":"left-and-right-are-of-different-types-left-type","errorCode":null,"errorMessage":"left and right are of different types. Left type:  {type(left)}. Right type: {type(right)}.","messagePattern":"left and right are of different types\\. Left type:  (.+?)\\. Right type: (.+?)\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/utils/_merge.py","lineNumber":205,"sourceCode":"    Args:\n        left: The first object to merge.\n        right: The other object to merge.\n\n    Returns:\n        The merged object.\n\n    Raises:\n        TypeError: If the key exists in both dictionaries but has a different type.\n        ValueError: If the two objects cannot be merged.\n    \"\"\"\n    if left is None or right is None:\n        return left if left is not None else right\n    if type(left) is not type(right):\n        msg = (\n            f\"left and right are of different types. Left type:  {type(left)}. Right \"\n            f\"type: {type(right)}.\"\n        )\n        raise TypeError(msg)\n    if isinstance(left, str):\n        return left + right\n    if isinstance(left, dict):\n        return merge_dicts(left, right)\n    if isinstance(left, list):\n        return merge_lists(left, right)\n    if left == right:\n        return left\n    msg = (\n        f\"Unable to merge {left=} and {right=}. Both must be of type str, dict, or \"\n        f\"list, or else be two equal objects.\"\n    )\n    raise ValueError(msg)\n","sourceCodeStart":187,"sourceCodeEnd":219,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/utils/_merge.py#L187-L219","documentation":"Raised by merge_dicts when left[key] and right[key] exist with different Python types — the per-key dispatch needs both sides to share a type to concatenate strings, merge dicts, or merge lists. This is the generic deep-merge utility behind prompt/data merging, not the message-chunk one. A type change on any shared key aborts the whole merge.","triggerScenarios":"merge_dicts({'a': 'x'}, {'a': ['x']}); merging template partials where one side supplies a string and the other a list for the same variable; merging config/data dicts assembled from JSON sources with schema drift; example_prompt kwargs built from mixed sources.","commonSituations":"Prompt templates with partial variables whose type differs between code defaults and runtime inputs; merging serialized examples where a field changed type between versions; dataclass/to-dict conversions producing lists vs scalars for the same field.","solutions":["Normalize both sides to the same type for shared keys before calling merge_dicts (e.g. wrap scalars in a list)","Restructure so the conflicting key is not present on both sides — pop it from one","Validate inputs upstream with a schema (pydantic) so type drift is caught with a clearer error","Catch TypeError and apply an explicit per-key resolution policy for known-volatile keys"],"exampleFix":"# before\nfrom langchain_core.utils import merge_dicts\nmerged = merge_dicts({\"docs\": \"a b\"}, {\"docs\": [\"a\", \"b\"]})  # TypeError\n# after\nleft = {\"docs\": [\"a b\"]}\nmerged = merge_dicts(left, {\"docs\": [\"a\", \"b\"]})  # list + list merges","handlingStrategy":"type-guard","validationCode":"shared = set(left) & set(right)\nfor k in shared:\n    if type(left[k]) is not type(right[k]):\n        msg = f\"key {k!r}: {type(left[k]).__name__} vs {type(right[k]).__name__}\"\n        raise TypeError(msg)  # clearer than the library's message","typeGuard":"from typing import Any\n\ndef dict_types_compatible(left: dict[str, Any], right: dict[str, Any]) -> bool:\n    return all(\n        type(left[k]) is type(right[k])\n        for k in set(left) & set(right)\n    )","tryCatchPattern":null,"preventionTips":["Normalize shared keys to one type (usually list) before deep-merging","Build prompt/example dicts from pydantic models so types are fixed","Add a pre-merge type check in test fixtures for merged configurations"],"tags":["merge","utilities","type-error","configuration"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}