{"record":{"id":"d2117cb909842cd6","repo":"mem0ai/mem0","slug":"all-header-keys-and-values-must-be-strings","errorCode":null,"errorMessage":"All header keys and values must be strings","messagePattern":"All header keys and values must be strings","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/configs/vector_stores/elasticsearch.py","lineNumber":51,"sourceCode":"        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)}\"\n            )\n        return values\n\n    model_config = ConfigDict(arbitrary_types_allowed=True)\n","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/configs/vector_stores/elasticsearch.py#L33-L69","documentation":"Raised by the Elasticsearch config's header validator when headers is a dict but at least one key or value is not a str. HTTP headers are string-to-string mappings; ints, bools, or None values pass the isinstance(headers, dict) check and then fail this per-item string check.","triggerScenarios":"headers={\"X-Retry\": 3} (int value), headers={None: \"v\"} (non-str key), or headers={\"flag\": True}. Typically values injected from typed config sources (env ints, YAML booleans).","commonSituations":"YAML parsing 'on'/'off' into booleans used as header values; numeric settings passed through without str() conversion; None values from optional config fields not filtered out.","solutions":["Convert all header values to strings: headers={k: str(v) for k, v in headers.items()}","Drop None values before passing headers: {k: v for k, v in headers.items() if v is not None}","Quote scalar header values in YAML/JSON so loaders keep them strings","Add a quick assert that all(k, v are str) 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_header_types(cfg: dict) -> None:\n    h = cfg.get(\"headers\")\n    if isinstance(h, dict):\n        bad = [k for k, v in h.items() if not isinstance(k, str) or not isinstance(v, str)]\n        if bad:\n            raise RuntimeError(f\"Header keys/values must be str, bad entries: {bad}\")","typeGuard":"def headers_all_str(cfg: dict) -> bool:\n    h = cfg.get(\"headers\")\n    return h is None or (isinstance(h, dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in h.items()))","tryCatchPattern":"from pydantic import ValidationError\ntry:\n    ElasticsearchConfig(**cfg)\nexcept ValidationError as e:\n    if \"keys and values must be strings\" in str(e):\n        # str() the values and drop Nones, then retry\n        ...","preventionTips":["Normalize headers: {k: str(v) for k, v in h.items() if v is not None}","Quote scalars in YAML so they stay strings","Unit-test config loaders for header typing"],"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-15T17:31:12.345Z"}