{"record":{"id":"8978bb485b5b16b3","repo":"langchain-ai/langchain","slug":"can-t-load-chat-prompt-without-template","errorCode":null,"errorMessage":"Can't load chat prompt without template","messagePattern":"Can't load chat prompt without template","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/prompts/loading.py","lineNumber":287,"sourceCode":"        msg = f\"Got unsupported file type {file_path.suffix}\"\n        raise ValueError(msg)\n    # Load the prompt from the config now.\n    return load_prompt_from_config(config, allow_dangerous_paths=allow_dangerous_paths)\n\n\ndef _load_chat_prompt(\n    config: dict[str, Any],\n    *,\n    allow_dangerous_paths: bool = False,  # noqa: ARG001\n) -> ChatPromptTemplate:\n    \"\"\"Load chat prompt from config.\"\"\"\n    messages = config.pop(\"messages\")\n    template = messages[0][\"prompt\"].pop(\"template\") if messages else None\n    config.pop(\"input_variables\")\n\n    if not template:\n        msg = \"Can't load chat prompt without template\"\n        raise ValueError(msg)\n\n    return ChatPromptTemplate.from_template(template=template, **config)\n\n\ntype_to_loader_dict: dict[str, Callable[..., BasePromptTemplate[str]]] = {\n    \"prompt\": _load_prompt,\n    \"few_shot\": _load_few_shot_prompt,\n    \"chat\": _load_chat_prompt,\n}\n","sourceCodeStart":269,"sourceCodeEnd":297,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/prompts/loading.py#L269-L297","documentation":"The legacy `chat` prompt loader (`_load_chat_prompt`) expects the config's first message to carry an inline `template` key that it pops to rebuild the prompt via `ChatPromptTemplate.from_template`. If `messages` is empty or the first message's `prompt` dict has no (or empty) `template`, it raises `ValueError: Can't load chat prompt without template`.","triggerScenarios":"Loading a `{\"_type\": \"chat\"}` config whose `messages` list is `[]`, or whose first message is `{\"prompt\": {}}` / has a `template_path` instead of inline `template`. Note: a missing `messages` key raises `KeyError` before this check.","commonSituations":"Serialized chat prompts whose messages used template files; empty-message configs from a failed export; chat configs from other tools that structure messages differently (e.g. tuples or role/content pairs).","solutions":["Ensure the first message contains an inline `template` string: `{\"messages\": [{\"prompt\": {\"template\": \"Hi {name}\"}}]}`.","Prefer modern serialization: `dumpd(chat_prompt)` / `loads(...)` from `langchain_core.load`, which handles arbitrary message structures.","Build chat prompts in code with `ChatPromptTemplate.from_messages([...])` instead of the legacy config format."],"exampleFix":"# before\n# {\"_type\": \"chat\", \"input_variables\": [], \"messages\": []}\nload_prompt('chat.json')  # ValueError\n\n# after\n# {\"_type\": \"chat\", \"input_variables\": [\"name\"],\n#  \"messages\": [{\"prompt\": {\"template\": \"Hi {name}\"}}]}\nload_prompt('chat.json')","handlingStrategy":"validation","validationCode":"msgs = config.get('messages') or []\nfirst = msgs[0].get('prompt', {}) if msgs else {}\nif not first.get('template'):\n    raise ValueError('chat config needs an inline template in the first message')\nload_prompt_from_config(config)","typeGuard":"def chat_config_has_template(config: dict) -> bool:\n    msgs = config.get('messages') or []\n    return bool(msgs) and bool((msgs[0] or {}).get('prompt', {}).get('template'))","tryCatchPattern":null,"preventionTips":["Prefer dumpd/dumps from langchain_core.load for chat prompts instead of the legacy chat config format.","Build chat prompts with ChatPromptTemplate.from_messages in code."],"tags":["prompts","chat","loading","config"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}