{"record":{"id":"f84b11061a908fd3","repo":"langchain-ai/langchain","slug":"failed-to-hash-metadata-e-please-use-a-dict-th","errorCode":null,"errorMessage":"Failed to hash metadata: {e}. Please use a dict that can be serialized using json.","messagePattern":"Failed to hash metadata: (.+?)\\. Please use a dict that can be serialized using json\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/indexing/api.py","lineNumber":221,"sourceCode":"    Returns:\n        Document with a unique identifier based on the hash of the content and metadata.\n    \"\"\"\n    metadata: dict[str, Any] = dict(document.metadata or {})\n\n    if callable(key_encoder):\n        # If key_encoder is a callable, we use it to generate the hash.\n        hash_ = key_encoder(document)\n    else:\n        # The hashes are calculated separate for the content and the metadata.\n        content_hash = _calculate_hash(document.page_content, algorithm=key_encoder)\n        try:\n            serialized_meta = json.dumps(metadata, sort_keys=True)\n        except Exception as e:\n            msg = (\n                f\"Failed to hash metadata: {e}. \"\n                f\"Please use a dict that can be serialized using json.\"\n            )\n            raise ValueError(msg) from e\n        metadata_hash = _calculate_hash(serialized_meta, algorithm=key_encoder)\n        hash_ = _calculate_hash(content_hash + metadata_hash, algorithm=key_encoder)\n\n    return Document(\n        # Assign a unique identifier based on the hash.\n        id=hash_,\n        page_content=document.page_content,\n        metadata=document.metadata,\n    )\n\n\n# This internal abstraction was imported by the langchain package internally, so\n# we keep it here for backwards compatibility.\nclass _HashedDocument:\n    def __init__(self, *args: Any, **kwargs: Any) -> None:\n        \"\"\"Raise an error if this class is instantiated.\"\"\"\n        msg = (\n            \"_HashedDocument is an internal abstraction that was deprecated in \"","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/indexing/api.py#L203-L239","documentation":"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.","triggerScenarios":"Indexing documents whose metadata includes non-JSON-serializable values: `datetime`, `set`, `Decimal`, `bytes`, `numpy.int64`, dataclass or Pydantic objects, `None` keys.","commonSituations":"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.","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`."],"exampleFix":"# before\ndoc = Document(\"text\", metadata={\"updated\": file_stat.st_mtime_datetime})  # datetime\nindex(vs, [doc], rm, cleanup=\"full\")\n\n# after\ndoc = Document(\"text\", metadata={\"updated\": file_stat.st_mtime_datetime.isoformat()})\nindex(vs, [doc], rm, cleanup=\"full\")","handlingStrategy":"validation","validationCode":"import json\n\ndef jsonable_metadata(md: dict) -> dict:\n    test = json.dumps(md, sort_keys=True)  # fail before indexing, not mid-run\n    return md\n\ndocs = [d.model_copy(update={\"metadata\": jsonable_metadata(d.metadata)}) for d in docs]\nindex(vs, docs, rm, cleanup=\"full\")","typeGuard":"def metadata_is_jsonable(md: dict) -> bool:\n    try:\n        json.dumps(md, sort_keys=True)\n        return True\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"try:\n    index(vs, docs, rm, cleanup=\"full\")\nexcept ValueError as e:\n    if \"Failed to hash metadata\" in str(e):\n        docs = [sanitize(d) for d in docs]  # coerce datetimes/sets/etc.\n        index(vs, docs, rm, cleanup=\"full\")\n    else:\n        raise","preventionTips":["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."],"tags":["indexing","serialization","metadata","json"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}