{"record":{"id":"0ea8da8de414bc8e","repo":"infiniflow/ragflow","slug":"invalid-label-format-value-r","errorCode":null,"errorMessage":"Invalid {label} format: {value!r}","messagePattern":"Invalid (.+?) format: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"api/db/services/dialog_service.py","lineNumber":1032,"sourceCode":"    \"\"\"\n    logging.debug(f\"use_sql: Question: {question}\")\n\n    # Determine which document engine we're using\n    if settings.DOC_ENGINE_INFINITY:\n        doc_engine = \"infinity\"\n    elif settings.DOC_ENGINE_OCEANBASE:\n        doc_engine = \"oceanbase\"\n    else:\n        doc_engine = \"es\"\n\n    def _assert_valid_uuid(value: str, label: str = \"id\") -> None:\n        if label == \"doc_id\" and str(value) == \"-999\":\n            return\n        try:\n            uuid.UUID(str(value))\n        except (ValueError, AttributeError, TypeError):\n            logger.warning(\"SQL injection guard rejected invalid %s value (length=%d)\", label, len(str(value)))\n            raise ValueError(f\"Invalid {label} format: {value!r}\")\n\n    if isinstance(doc_ids, str):\n        doc_ids = [doc_id for doc_id in doc_ids.split(\",\") if doc_id]\n    else:\n        doc_ids = [doc_id for doc_id in doc_ids or [] if doc_id]\n\n    # Construct the full table name\n    # For Elasticsearch: ragflow_{tenant_id} (kb_id is in WHERE clause)\n    # For Infinity: ragflow_{tenant_id}_{kb_id} (each KB has its own table)\n    base_table = index_name(tenant_id)\n    if doc_engine == \"infinity\" and kb_ids and len(kb_ids) == 1:\n        # Infinity: append kb_id to table name — validate before interpolating\n        _assert_valid_uuid(kb_ids[0], \"kb_id\")\n        table_name = f\"{base_table}_{kb_ids[0]}\"\n        logging.debug(f\"use_sql: Using Infinity table name: {table_name}\")\n    else:\n        # Elasticsearch/OpenSearch: use base index name\n        table_name = base_table","sourceCodeStart":1014,"sourceCodeEnd":1050,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/db/services/dialog_service.py#L1014-L1050","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","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)."],"exampleFix":"# before\nretrieval(doc_ids=[\"all\"])\n# after\nretrieval(doc_ids=[d.id for d in DocumentService.list_documents(kb_id)])","handlingStrategy":"validation","validationCode":"import uuid\n\ndef valid_ids(values, allow_sentinel=False):\n    out = []\n    for v in values or []:\n        s = str(v or '').strip()\n        if allow_sentinel and s == '-999':\n            out.append(s); continue\n        uuid.UUID(s)  # raises on anything non-UUID\n        out.append(s)\n    return out\n\ndoc_ids = valid_ids(doc_ids, allow_sentinel=True)\nkb_ids = valid_ids(kb_ids)","typeGuard":"function isUuid(v: unknown): v is string {\n  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());\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["security","sql-injection","uuid","validation","retrieval"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}