langchain-ai/langchain · error · ValueError
Failed to hash metadata: {e}. Please use a dict that can be
Error message
Failed to hash metadata: {e}. Please use a dict that can be serialized using json. What it means
Raised by `_get_document_with_hash` in `langchain_core.indexing.api`. Before hashing, document metadata is serialized with `json.dumps(..., sort_keys=True)` so the hash is deterministic. If metadata contains values JSON cannot serialize (sets, datetimes, custom objects, numpy types), serialization fails and the error chains the original exception (`raise ... from e`) so you can see the underlying cause.
Source
Thrown at libs/core/langchain_core/indexing/api.py:221
Returns:
Document with a unique identifier based on the hash of the content and metadata.
"""
metadata: dict[str, Any] = dict(document.metadata or {})
if callable(key_encoder):
# If key_encoder is a callable, we use it to generate the hash.
hash_ = key_encoder(document)
else:
# The hashes are calculated separate for the content and the metadata.
content_hash = _calculate_hash(document.page_content, algorithm=key_encoder)
try:
serialized_meta = json.dumps(metadata, sort_keys=True)
except Exception as e:
msg = (
f"Failed to hash metadata: {e}. "
f"Please use a dict that can be serialized using json."
)
raise ValueError(msg) from e
metadata_hash = _calculate_hash(serialized_meta, algorithm=key_encoder)
hash_ = _calculate_hash(content_hash + metadata_hash, algorithm=key_encoder)
return Document(
# Assign a unique identifier based on the hash.
id=hash_,
page_content=document.page_content,
metadata=document.metadata,
)
# This internal abstraction was imported by the langchain package internally, so
# we keep it here for backwards compatibility.
class _HashedDocument:
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Raise an error if this class is instantiated."""
msg = (
"_HashedDocument is an internal abstraction that was deprecated in "View on GitHub (pinned to e32fa9a52e)
Solutions
- Coerce metadata values to JSON primitives before indexing: convert datetimes with `.isoformat()`, sets to lists, numpy scalars with `.item()`.
- Use a `default=str` style sanitizer: `metadata = {k: _jsonable(v) for k, v in metadata.items()}`.
- Or supply a callable `key_encoder` that serializes metadata your own way, bypassing `json.dumps`.
Example fix
# before
doc = Document("text", metadata={"updated": file_stat.st_mtime_datetime}) # datetime
index(vs, [doc], rm, cleanup="full")
# after
doc = Document("text", metadata={"updated": file_stat.st_mtime_datetime.isoformat()})
index(vs, [doc], rm, cleanup="full") Defensive patterns
Strategy: validation
Validate before calling
import json
def jsonable_metadata(md: dict) -> dict:
test = json.dumps(md, sort_keys=True) # fail before indexing, not mid-run
return md
docs = [d.model_copy(update={"metadata": jsonable_metadata(d.metadata)}) for d in docs]
index(vs, docs, rm, cleanup="full") Type guard
def metadata_is_jsonable(md: dict) -> bool:
try:
json.dumps(md, sort_keys=True)
return True
except (TypeError, ValueError):
return False Try / catch
try:
index(vs, docs, rm, cleanup="full")
except ValueError as e:
if "Failed to hash metadata" in str(e):
docs = [sanitize(d) for d in docs] # coerce datetimes/sets/etc.
index(vs, docs, rm, cleanup="full")
else:
raise Prevention
- Sanitize loader metadata at creation: isoformat() datetimes, list() sets, .item() numpy scalars.
- Run json.dumps over each doc's metadata in a preflight loop before starting a long index job.
When it happens
Trigger: Indexing documents whose metadata includes non-JSON-serializable values: `datetime`, `set`, `Decimal`, `bytes`, `numpy.int64`, dataclass or Pydantic objects, `None` keys.
Common situations: Loaders that attach file stats (`datetime` mtimes), unstructured-style metadata with numpy scalars, `set` fields from preprocessing, arbitrary objects placed in metadata for later retrieval.
Related errors
- `default` should not be passed to dumps
- Batch size must be a positive integer, got {size}.
- source_id_key should be either None, a string or a callable.
- Unsupported hashing algorithm: {algorithm}
- _HashedDocument is an internal abstraction that was deprecat
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/f84b11061a908fd3.
Report an issue: GitHub.