langchain-ai/langchain · error · ValueError
Unsupported hashing algorithm: {algorithm}
Error message
Unsupported hashing algorithm: {algorithm} What it means
Raised by `_calculate_hash` in `langchain_core.indexing.api`. The indexing API hashes document content and metadata to detect changes; supported algorithms are sha1, sha256, sha512, and blake2b. The parameter is typed as a Literal, so in a well-typed program this branch is unreachable (`# type: ignore[unreachable]`), but at runtime an arbitrary string reaches it and is rejected.
Source
Thrown at libs/core/langchain_core/indexing/api.py:172
"""Raised when an indexing operation fails."""
def _calculate_hash(
text: str, algorithm: Literal["sha1", "sha256", "sha512", "blake2b"]
) -> str:
"""Return a hexadecimal digest of *text* using *algorithm*."""
if algorithm == "sha1":
# Calculate the SHA-1 hash and return it as a UUID.
digest = hashlib.sha1(text.encode("utf-8"), usedforsecurity=False).hexdigest()
return str(uuid.uuid5(NAMESPACE_UUID, digest))
if algorithm == "blake2b":
return hashlib.blake2b(text.encode("utf-8")).hexdigest()
if algorithm == "sha256":
return hashlib.sha256(text.encode("utf-8")).hexdigest()
if algorithm == "sha512":
return hashlib.sha512(text.encode("utf-8")).hexdigest()
msg = f"Unsupported hashing algorithm: {algorithm}" # type: ignore[unreachable]
raise ValueError(msg)
def _get_document_with_hash(
document: Document,
*,
key_encoder: Callable[[Document], str]
| Literal["sha1", "sha256", "sha512", "blake2b"],
) -> Document:
"""Calculate a hash of the document, and assign it to the uid.
When using one of the predefined hashing algorithms, the hash is calculated
by hashing the content and the metadata of the document.
Args:
document: Document to hash.
key_encoder: Hashing algorithm to use for hashing the document.
If not provided, a default encoder using SHA-1 will be used.
SHA-1 is not collision-resistant, and a motivated attackerView on GitHub (pinned to e32fa9a52e)
Solutions
- Use one of the supported names exactly: "sha1", "sha256", "sha512", or "blake2b".
- If you need a custom digest, pass a callable `key_encoder=lambda doc: ...` instead of an algorithm string.
- Validate the config value against the allowed set at startup.
Example fix
# before index(vs, docs, rm, key_encoder="sha-256", cleanup="full") # after index(vs, docs, rm, key_encoder="sha256", cleanup="full")
Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = {"sha1", "sha256", "sha512", "blake2b"}
if key_encoder not in ALLOWED and not callable(key_encoder):
raise ValueError(f"algorithm must be one of {sorted(ALLOWED)} or a callable")
index(vs, docs, rm, key_encoder=key_encoder, cleanup="full") Type guard
def is_supported_algorithm(name: str) -> bool:
return name in {"sha1", "sha256", "sha512", "blake2b"} Prevention
- Type config fields as Literal["sha1","sha256","sha512","blake2b"] in your settings model.
- Watch for hyphenated names like 'sha-256' from user input; normalize before passing.
When it happens
Trigger: Passing `index(..., key_encoder="md5")` or any algorithm name outside the Literal set; passing `hash_algorithm`/`key_encoder` from user config without validation; version skew where an older code path forwards a raw string.
Common situations: Security policies that mandate a specific hash (e.g. trying md5/sha384); config files shared across tools where the algorithm field is free-text; typos like "sha-256" instead of "sha256".
Related errors
- Batch size must be a positive integer, got {size}.
- source_id_key should be either None, a string or a callable.
- cleanup should be one of 'incremental', 'full', 'scoped_full
- invalid IP address
- Failed to resolve hostname '{hostname}': {e}
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/9145e24140e9d211.
Report an issue: GitHub.