{"record":{"id":"e2eada62a3097457","repo":"mem0ai/mem0","slug":"headers-must-be-a-dictionary","errorCode":null,"errorMessage":"headers must be a dictionary","messagePattern":"headers must be a dictionary","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/configs/vector_stores/elasticsearch.py","lineNumber":46,"sourceCode":"        # Check if either cloud_id or host/port is provided\n        if not values.get(\"cloud_id\") and not values.get(\"host\"):\n            raise ValueError(\"Either cloud_id or host must be provided\")\n\n        # Check if authentication is provided\n        if not any([values.get(\"api_key\"), (values.get(\"user\") and values.get(\"password\"))]):\n            raise ValueError(\"Either api_key or user/password must be provided\")\n\n        return values\n\n    @model_validator(mode=\"before\")\n    @classmethod\n    def validate_headers(cls, values: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"Validate headers format and content\"\"\"\n        headers = values.get(\"headers\")\n        if headers is not None:\n            # Check if headers is a dictionary\n            if not isinstance(headers, dict):\n                raise ValueError(\"headers must be a dictionary\")\n            \n            # Check if all keys and values are strings\n            for key, value in headers.items():\n                if not isinstance(key, str) or not isinstance(value, str):\n                    raise ValueError(\"All header keys and values must be strings\")\n        \n        return values\n\n    @model_validator(mode=\"before\")\n    @classmethod\n    def validate_extra_fields(cls, values: Dict[str, Any]) -> Dict[str, Any]:\n        allowed_fields = set(cls.model_fields.keys())\n        input_fields = set(values.keys())\n        extra_fields = input_fields - allowed_fields\n        if extra_fields:\n            raise ValueError(\n                f\"Extra fields not allowed: {', '.join(extra_fields)}. \"\n                f\"Please input only the following fields: {', '.join(allowed_fields)}\"","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/configs/vector_stores/elasticsearch.py#L28-L64","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nElasticsearchConfig(host=\"h\", api_key=\"k\", headers=\"X-Opaque-Id: 42\")\n\n# after\nElasticsearchConfig(host=\"h\", api_key=\"k\", headers={\"X-Opaque-Id\": \"42\"})","handlingStrategy":"type-guard","validationCode":"def validate_es_headers(cfg: dict) -> None:\n    h = cfg.get(\"headers\")\n    if h is not None and not isinstance(h, dict):\n        raise RuntimeError(\"'headers' must be a dict of name -> value\")","typeGuard":"def headers_is_dict(cfg: dict) -> bool:\n    h = cfg.get(\"headers\")\n    return h is None or isinstance(h, dict)","tryCatchPattern":"from pydantic import ValidationError\ntry:\n    ElasticsearchConfig(**cfg)\nexcept ValidationError as e:\n    if \"headers must be a dictionary\" in str(e):\n        # coerce/parse headers into a dict, then retry\n        ...","preventionTips":["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"],"tags":["pydantic","configuration","vector-store","elasticsearch","headers","type-mismatch"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}