infiniflow/ragflow · error · ValueError
Invalid {label} format: {value!r}
Error message
Invalid {label} format: {value!r} What it means
ValueError from the SQL-injection guard in dialog_service's retrieval query builder: doc_ids/kb_ids values (and other interpolated identifiers) must parse as UUIDs, with the single sentinel '-999' allowed for doc_id. Non-UUID input is logged as a rejected injection attempt and rejected before table-name/WHERE interpolation.
Source
Thrown at api/db/services/dialog_service.py:1032
"""
logging.debug(f"use_sql: Question: {question}")
# Determine which document engine we're using
if settings.DOC_ENGINE_INFINITY:
doc_engine = "infinity"
elif settings.DOC_ENGINE_OCEANBASE:
doc_engine = "oceanbase"
else:
doc_engine = "es"
def _assert_valid_uuid(value: str, label: str = "id") -> None:
if label == "doc_id" and str(value) == "-999":
return
try:
uuid.UUID(str(value))
except (ValueError, AttributeError, TypeError):
logger.warning("SQL injection guard rejected invalid %s value (length=%d)", label, len(str(value)))
raise ValueError(f"Invalid {label} format: {value!r}")
if isinstance(doc_ids, str):
doc_ids = [doc_id for doc_id in doc_ids.split(",") if doc_id]
else:
doc_ids = [doc_id for doc_id in doc_ids or [] if doc_id]
# Construct the full table name
# For Elasticsearch: ragflow_{tenant_id} (kb_id is in WHERE clause)
# For Infinity: ragflow_{tenant_id}_{kb_id} (each KB has its own table)
base_table = index_name(tenant_id)
if doc_engine == "infinity" and kb_ids and len(kb_ids) == 1:
# Infinity: append kb_id to table name — validate before interpolating
_assert_valid_uuid(kb_ids[0], "kb_id")
table_name = f"{base_table}_{kb_ids[0]}"
logging.debug(f"use_sql: Using Infinity table name: {table_name}")
else:
# Elasticsearch/OpenSearch: use base index name
table_name = base_tableView on GitHub (pinned to 554fb1133a)
Solutions
- Send only real UUIDs for doc_ids/kb_ids (server-generated document and dataset ids).
- Use the '-999' sentinel only for the documented doc_id wildcard case.
- Filter/validate ids client-side before calling the API (see validationCode).
Example fix
# before retrieval(doc_ids=["all"]) # after retrieval(doc_ids=[d.id for d in DocumentService.list_documents(kb_id)])
Defensive patterns
Strategy: validation
Validate before calling
import uuid
def valid_ids(values, allow_sentinel=False):
out = []
for v in values or []:
s = str(v or '').strip()
if allow_sentinel and s == '-999':
out.append(s); continue
uuid.UUID(s) # raises on anything non-UUID
out.append(s)
return out
doc_ids = valid_ids(doc_ids, allow_sentinel=True)
kb_ids = valid_ids(kb_ids) Type guard
function isUuid(v: unknown): v is string {
return typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v.trim());
} Prevention
- Never forward raw user input as doc_ids/kb_ids — always map through id lookups.
- Treat '-999' as the only special doc_id value; reject other placeholders early.
When it happens
Trigger: Calling retrieval with doc_ids containing arbitrary strings (e.g. "1; DROP TABLE", 'all', or an untrimmed non-UUID id), or a kb_id/tenant_id that is not a UUID — any value passed to _assert_valid_uuid that fails uuid.UUID().
Common situations: Clients using legacy numeric ids or placeholders like 'all'/null coerced to 'None'; test scripts passing raw strings; integrations forwarding user input directly as doc_ids.
Related errors
- dataset_id (or kb_id/knowledge_id) is required for retrieval
- Error parsing ID Token: {e}
- Unsupported auth_type: {auth_type}
- 101
- invalid_uuid_format
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/0ea8da8de414bc8e.
Report an issue: GitHub.