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

  1. Coerce metadata values to JSON primitives before indexing: convert datetimes with `.isoformat()`, sets to lists, numpy scalars with `.item()`.
  2. Use a `default=str` style sanitizer: `metadata = {k: _jsonable(v) for k, v in metadata.items()}`.
  3. 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

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


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/f84b11061a908fd3. Report an issue: GitHub.