{"record":{"id":"c8fada878c7ae5cf","repo":"run-llama/llama_index","slug":"both-metadata-value-and-value-should-be-strings-to-c8fada","errorCode":null,"errorMessage":"Both metadata_value and value should be strings to be used with a TEXT_MATCH_INSENSITIVE filter","messagePattern":"Both metadata_value and value should be strings to be used with a TEXT_MATCH_INSENSITIVE filter","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/vector_stores/utils.py","lineNumber":148,"sourceCode":"            if operator == FilterOperator.LTE:\n                return metadata_value <= value\n            if operator == FilterOperator.IN:\n                return metadata_value in value\n            if operator == FilterOperator.NIN:\n                return metadata_value not in value\n            if operator == FilterOperator.CONTAINS:\n                return value in metadata_value\n            if operator == FilterOperator.TEXT_MATCH:\n                if isinstance(value, str) and isinstance(metadata_value, str):\n                    return value in metadata_value\n                raise TypeError(\n                    \"Both metadata_value and value should be strings to be used with a \"\n                    \"TEXT_MATCH filter\"\n                )\n            if operator == FilterOperator.TEXT_MATCH_INSENSITIVE:\n                if isinstance(value, str) and isinstance(metadata_value, str):\n                    return value.lower() in metadata_value.lower()\n                raise TypeError(\n                    \"Both metadata_value and value should be strings to be used with a \"\n                    \"TEXT_MATCH_INSENSITIVE filter\"\n                )\n            if operator == FilterOperator.ALL:\n                return all(val in metadata_value for val in value)\n            if operator == FilterOperator.ANY:\n                return any(val in metadata_value for val in value)\n\n            raise ValueError(f\"Invalid operator: {operator}\")\n\n        metadata = metadata_lookup_fn(node_id)\n\n        filter_matches_list = []\n        for filter_ in filter_list:\n            if isinstance(filter_, MetadataFilters):\n                raise ValueError(\"Nested MetadataFilters are not supported.\")\n\n            filter_matches = True","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/vector_stores/utils.py#L130-L166","documentation":"Same guard as TEXT_MATCH but for FilterOperator.TEXT_MATCH_INSENSITIVE: the case-insensitive substring check calls `.lower()` on both sides, so both the filter value and the node's metadata value must be str. A TypeError is raised when either side is a non-string type, instead of an AttributeError from calling .lower() on an int. This is evaluated per candidate node during client-side filtering.","triggerScenarios":"Querying with `operator=FilterOperator.TEXT_MATCH_INSENSITIVE` where the filter value is non-str (int, None, list) or where stored metadata under the filter key is numeric/None in any node being evaluated; e.g. `MetadataFilter(key=\"tags\", value=[\"ai\"], operator=TEXT_MATCH_INSENSITIVE)`.","commonSituations":"Passing arrays to a single-value operator (should use IN/ANY/CONTAINS); optional metadata fields that are None on some documents; mixed-type metadata after schema drift or multi-source ingestion; forgetting to stringify config-supplied filter values.","solutions":["Pass a str value: `MetadataFilter(key=\"name\", value=\"alice\", operator=FilterOperator.TEXT_MATCH_INSENSITIVE)`.","For collections use `FilterOperator.IN` / `ANY` / `CONTAINS` instead of text-match operators.","Normalize metadata types at ingestion so filtered fields are always str (or always the intended type).","Skip None values by using `FilterOperator.IS_EMPTY` for missing-field checks."],"exampleFix":"# before\nf = MetadataFilter(key=\"tags\", value=[\"ai\"], operator=FilterOperator.TEXT_MATCH_INSENSITIVE)\n\n# after\nf = MetadataFilter(key=\"tags\", value=\"ai\", operator=FilterOperator.TEXT_MATCH_INSENSITIVE)\n# or for collections:\nf = MetadataFilter(key=\"tags\", value=[\"ai\"], operator=FilterOperator.IN)","handlingStrategy":"type-guard","validationCode":"def insensitive_filter_valid(value) -> bool:\n    return isinstance(value, str)","typeGuard":"def is_insensitive_match_safe(filter_, sample_metadata: dict) -> bool:\n    from llama_index.core.vector_stores import FilterOperator\n    if filter_.operator is not FilterOperator.TEXT_MATCH_INSENSITIVE:\n        return True\n    stored = sample_metadata.get(filter_.key)\n    return isinstance(filter_.value, str) and isinstance(stored, str)","tryCatchPattern":"try:\n    result = store.query(query)\nexcept TypeError as e:\n    if \"TEXT_MATCH_INSENSITIVE\" in str(e):\n        # switch to IN for collections or coerce value to str, then rebuild query\n        raise ValueError(\"use str values or FilterOperator.IN for lists\") from e\n    raise","preventionTips":["Use IN/ANY/CONTAINS for list values, TEXT_MATCH* only for single strings.","Normalize optional fields to \"\" or use IS_EMPTY instead of relying on None.","Test filters against representative metadata samples before deploying."],"tags":["metadata-filters","type-error","case-insensitive","python"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}