langchain-ai/langchain · error · TypeError
Expected either a dictionary with a 'type' key or an object
Error message
Expected either a dictionary with a 'type' key or an object with a 'type' attribute. Instead got type {type(v)}. What it means
Raised by the internal helper `_get_type` when a value passed to message serialization/conversion is neither a dict containing a 'type' key nor an object with a `type` attribute. The helper is used to derive the message-type discriminator string during (de)serialization of message-like values.
Source
Thrown at libs/core/langchain_core/messages/utils.py:79
_HAS_LANGCHAIN_TEXT_SPLITTERS = True
except ImportError:
_HAS_LANGCHAIN_TEXT_SPLITTERS = False
logger = logging.getLogger(__name__)
def _get_type(v: Any) -> str:
"""Get the type associated with the object for serialization purposes."""
if isinstance(v, dict) and "type" in v:
result = v["type"]
elif hasattr(v, "type"):
result = v.type
else:
msg = (
f"Expected either a dictionary with a 'type' key or an object "
f"with a 'type' attribute. Instead got type {type(v)}."
)
raise TypeError(msg)
if not isinstance(result, str):
msg = f"Expected 'type' to be a str, got {type(result).__name__}"
raise TypeError(msg)
return result
AnyMessage = Annotated[
Annotated[AIMessage, Tag(tag="ai")]
| Annotated[HumanMessage, Tag(tag="human")]
| Annotated[ChatMessage, Tag(tag="chat")]
| Annotated[SystemMessage, Tag(tag="system")]
| Annotated[FunctionMessage, Tag(tag="function")]
| Annotated[ToolMessage, Tag(tag="tool")]
| Annotated[AIMessageChunk, Tag(tag="AIMessageChunk")]
| Annotated[HumanMessageChunk, Tag(tag="HumanMessageChunk")]
| Annotated[ChatMessageChunk, Tag(tag="ChatMessageChunk")]
| Annotated[SystemMessageChunk, Tag(tag="SystemMessageChunk")]
| Annotated[FunctionMessageChunk, Tag(tag="FunctionMessageChunk")]View on GitHub (pinned to e32fa9a52e)
Solutions
- Add a 'type' key to the dict ('human', 'ai', 'system', 'tool', ...) or rename 'role' to 'type' where the API expects the langchain shape
- Pass proper `BaseMessage` instances (`HumanMessage`, `AIMessage`, ...) instead of raw dicts
- If using OpenAI-style dicts, use `convert_to_messages`/`convert_to_openai_messages` helpers instead of the serialization path directly
Example fix
# before
msg = {'role': 'user', 'content': 'hi'}
# after
msg = {'type': 'human', 'content': 'hi'}
# or
from langchain_core.messages import HumanMessage
msg = HumanMessage('hi') Defensive patterns
Strategy: validation
Validate before calling
def has_type_discriminator(v) -> bool:
return (isinstance(v, dict) and isinstance(v.get('type'), str)) or (hasattr(v, 'type') and isinstance(getattr(v, 'type'), str)) Type guard
from typing import Any
def is_message_like(v: Any) -> bool:
if isinstance(v, dict):
return isinstance(v.get('type'), str)
return isinstance(getattr(v, 'type', None), str) Try / catch
try:
t = _get_type(v)
except TypeError:
# normalize and retry once with an explicit type
v = {**v, 'type': 'human'} if isinstance(v, dict) else v
t = _get_type(v) Prevention
- Always build messages with BaseMessage classes or dicts containing a string 'type' key
- Validate external payloads at the boundary before passing them to langchain
- Prefer convert_to_messages for OpenAI-style 'role' dicts
When it happens
Trigger: Passing a plain dict without a 'type' key (e.g. `{'role': 'user', 'content': 'hi'}`) or an arbitrary object without a `.type` attribute into code paths that call `_get_type`, such as message dict round-tripping utilities.
Common situations: Hand-built message dicts from OpenAI-style payloads that use 'role' instead of 'type'; custom dataclasses passed where a `BaseMessage` or typed dict is expected; partial JSON loaded from a log with the 'type' field stripped.
Related errors
- Expected 'type' to be a str, got {type(result).__name__}
- Failed to hash metadata: {e}. Please use a dict that can be
- {save_path} must be json or yaml
- Expected Serializable, got {type(obj)}
- `default` should not be passed to dumps
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/fa1ab0eea8921cce.
Report an issue: GitHub.