jd-opensource/joyagent-jdgenie · error · ValueError
❌ 不支持的过滤值类型: ,字段
Error message
❌ 不支持的过滤值类型: {type(val)},字段: {key} What it means
QdrantUtils.delete builds a Filter from a filters dict and raises ValueError when a field's value is of an unsupported type for the condition builder. Supported shapes are match-style values and range dicts ({"gte":..,"lte":..}); anything else (nested dict without range ops, list, None value) is rejected.
Solutions
- Convert list values to explicit must/should match conditions (one FieldCondition per element) before calling delete
- Use only scalars for equality: filters={"status": "old"} instead of filters={"status": ["a","b"]}
- For numeric comparisons use the range dict form: filters={"created_at": {"gte": 1700000000, "lte": 1800000000}}
- Extend the filter builder to handle the unsupported type instead of raising, if lists are a legitimate use case
Example fix
// before
qdrant.delete(filters={"category": ["a", "b"]}) # ValueError: 不支持的过滤值类型: list
// after
for cat in ["a", "b"]:
qdrant.delete(filters={"category": cat}) Defensive patterns
Strategy: type-guard
Validate before calling
RANGE_OPS = {'gte','lte','gt','lt'}
def delete_filters_supported(filters):
for key, val in (filters or {}).items():
if isinstance(val, dict):
if not (set(val) & RANGE_OPS):
return False, f'{key}: dict without range ops'
elif not isinstance(val, (str, int, float, bool)):
return False, f'{key}: {type(val).__name__} unsupported'
return True, None Type guard
def is_scalar_or_range(v):
return isinstance(v, (str, int, float, bool)) or (isinstance(v, dict) and any(k in v for k in ('gte','lte','gt','lt'))) Try / catch
try:
qdrant.delete(filters=filters)
except ValueError as e:
logger.error('unsupported filter shape: %s', e)
# fall back to per-scalar deletes or fix the filter Prevention
- Keep filter values scalar or range-op dicts
- Translate cross-store filter syntax before calling Qdrant
- Test filter dicts against search() (same builder) before delete
- Document supported filter shapes in shared utils
When it happens
Trigger: delete(filters={...}) where some field value is not a scalar (str/int/float/bool) and not a dict containing range operators like gte/lte/gt/lt — e.g. filters={"tags": ["a","b"]} (list) or a nested dict of unsupported structure.
Common situations: Passing SQL/elastic-style query dicts into Qdrant filters; assuming list values mean 'match any'; a shared filter-building helper used by search() reused with wrong value shapes; schema drift where a field became an array in stored payloads.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
AI-assisted analysis of jd-opensource/joyagent-jdgenie@2417e0b8b6 (2026-09-08).
Data as JSON: /api/errors/c91f856173369fe0.
Report an issue: GitHub.
Appendix: source
Thrown at genie-tool/genie_tool/util/qdrant_utils.py:198
for key, val in filters.items():
if isinstance(val, (str, bool, int, float)):
must_conditions.append(
FieldCondition(key=key, match=MatchValue(value=val))
)
elif isinstance(val, list):
must_conditions.append(
FieldCondition(key=key, match=MatchAny(any=val))
)
elif isinstance(val, dict):
range_args = {}
for op in ["gte", "gt", "lte", "lt"]:
if op in val:
range_args[op] = val[op]
must_conditions.append(
FieldCondition(key=key, range=Range(**range_args))
)
else:
raise ValueError(f"❌ 不支持的过滤值类型: {type(val)},字段: {key}")
query_filter = Filter(must=must_conditions) if must_conditions else None
delete_request = self.client.delete(
collection_name=self.collection_name,
points_selector=query_filter # 👈 旧版也支持
)
return self.client.delete(collection_name=self.collection_name, points_selector=delete_request)
def search(self, query_vector, filters):
must_conditions = []
for key, val in filters.items():
if isinstance(val, (str, bool, int, float)):
must_conditions.append(
FieldCondition(
key=key,View on GitHub (pinned to 2417e0b8b6)