mem0ai/mem0 · error · ValueError
headers must be a dictionary
Error message
headers must be a dictionary
What it means
Raised by the Elasticsearch config's header validator when the 'headers' option is provided but is not a dict. Mem0 passes custom HTTP headers to the underlying Elasticsearch client, which requires a mapping of header name to value; strings, lists, or tuples are rejected at config validation time.
Source
Thrown at mem0/configs/vector_stores/elasticsearch.py:46
# Check if either cloud_id or host/port is provided
if not values.get("cloud_id") and not values.get("host"):
raise ValueError("Either cloud_id or host must be provided")
# Check if authentication is provided
if not any([values.get("api_key"), (values.get("user") and values.get("password"))]):
raise ValueError("Either api_key or user/password must be provided")
return values
@model_validator(mode="before")
@classmethod
def validate_headers(cls, values: Dict[str, Any]) -> Dict[str, Any]:
"""Validate headers format and content"""
headers = values.get("headers")
if headers is not None:
# Check if headers is a dictionary
if not isinstance(headers, dict):
raise ValueError("headers must be a dictionary")
# Check if all keys and values are strings
for key, value in headers.items():
if not isinstance(key, str) or not isinstance(value, str):
raise ValueError("All header keys and values must be strings")
return values
@model_validator(mode="before")
@classmethod
def validate_extra_fields(cls, values: Dict[str, Any]) -> Dict[str, Any]:
allowed_fields = set(cls.model_fields.keys())
input_fields = set(values.keys())
extra_fields = input_fields - allowed_fields
if extra_fields:
raise ValueError(
f"Extra fields not allowed: {', '.join(extra_fields)}. "
f"Please input only the following fields: {', '.join(allowed_fields)}"View on GitHub (pinned to 001c235229)
Solutions
- Provide headers as a dict: headers={"Authorization": "Bearer x"}
- If headers come from a list of 'k: v' strings, parse them into a dict before constructing the config
- Omit 'headers' entirely when no custom headers are needed
- Add a unit assertion that headers is a dict in config-loading code
Example fix
# before
ElasticsearchConfig(host="h", api_key="k", headers="X-Opaque-Id: 42")
# after
ElasticsearchConfig(host="h", api_key="k", headers={"X-Opaque-Id": "42"}) Defensive patterns
Strategy: type-guard
Validate before calling
def validate_es_headers(cfg: dict) -> None:
h = cfg.get("headers")
if h is not None and not isinstance(h, dict):
raise RuntimeError("'headers' must be a dict of name -> value") Type guard
def headers_is_dict(cfg: dict) -> bool:
h = cfg.get("headers")
return h is None or isinstance(h, dict) Try / catch
from pydantic import ValidationError
try:
ElasticsearchConfig(**cfg)
except ValidationError as e:
if "headers must be a dictionary" in str(e):
# coerce/parse headers into a dict, then retry
... Prevention
- Never pass raw 'k: v' strings; parse them into a dict first
- Keep headers in structured config (YAML mappings), not strings
- Omit headers when unused
When it happens
Trigger: Passing headers as anything other than a dict, e.g. headers='Authorization: Bearer x' (a string), headers=[('x','y')] (list of tuples), or headers=None wrapped in a list by a config loader.
Common situations: Translating curl-style '-H' header strings directly into config; JSON/YAML configs where headers collapse to a string; programmatic config builders defaulting headers to a serialized form.
Related errors
- All header keys and values must be strings
- Either cloud_id or host must be provided
- Either api_key or user/password must be provided
- Extra fields not allowed: {', '.join(extra_fields)}. Please
- Either 'password' must be provided or 'use_azure_credential'
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/e2eada62a3097457.
Report an issue: GitHub.