infiniflow/ragflow · error · LookupError
Tenant not found
Error message
Tenant not found
What it means
Raised by TenantLLMService.get_model_config when TenantService.get_by_id(tenant_id) fails, i.e. no tenant row matches the id. The model-config resolution needs tenant defaults (embd_id, llm_id, etc.), so an unknown tenant aborts immediately with LookupError.
Source
Thrown at api/db/services/tenant_llm_service.py:134
# model name must be xxx@yyy
try:
model_factories = settings.FACTORY_LLM_INFOS
model_providers = set([f["name"] for f in model_factories])
if arr[-1] not in model_providers:
return model_name, None
return arr[0], arr[-1]
except Exception as e:
logging.exception(f"TenantLLMService.split_model_name_and_factory got exception: {e}")
return model_name, None
@classmethod
@DB.connection_context()
def get_model_config(cls, tenant_id, llm_type, llm_name=None):
from api.db.services.llm_service import LLMService
e, tenant = TenantService.get_by_id(tenant_id)
if not e:
raise LookupError("Tenant not found")
if llm_type == LLMType.EMBEDDING.value:
mdlnm = tenant.embd_id if not llm_name else llm_name
elif llm_type == LLMType.ASR.value:
mdlnm = tenant.asr_id if not llm_name else llm_name
elif llm_type == LLMType.VISION.value:
mdlnm = tenant.img2txt_id if not llm_name else llm_name
elif llm_type == LLMType.CHAT.value:
mdlnm = tenant.llm_id if not llm_name else llm_name
elif llm_type == LLMType.RERANK:
mdlnm = tenant.rerank_id if not llm_name else llm_name
elif llm_type == LLMType.TTS:
mdlnm = tenant.tts_id if not llm_name else llm_name
elif llm_type == LLMType.OCR:
if not llm_name:
raise LookupError("OCR model name is required")
mdlnm = llm_name
else:View on GitHub (pinned to 554fb1133a)
Solutions
- Verify the tenant id exists: SELECT id FROM tenant WHERE id = ... or via the user/tenant API.
- Obtain tenant_id from the authenticated session/API key rather than hard-coding it.
- If the tenant was deleted, recreate the user/tenant or use a valid one.
- Ensure all RAGFlow instances connect to the same database in HA setups.
Defensive patterns
Strategy: validation
Validate before calling
ok, _tenant = TenantService.get_by_id(tenant_id)
if not ok:
return json_error_response('tenant not found', 401) Type guard
import uuid as _uuid
def is_valid_tenant_id(tenant_id: str) -> bool:
try:
_uuid.UUID(str(tenant_id))
except (ValueError, TypeError):
return False
return TenantService.get_by_id(tenant_id)[0] Try / catch
try:
cfg = TenantLLMService.get_model_config(tenant_id, llm_type, llm_name)
except LookupError as e:
if 'Tenant not found' in str(e):
abort(401, 'unknown tenant')
raise Prevention
- Derive tenant_id from the authenticated request, never from configuration files.
- Re-fetch stored tenant ids after re-provisioning a database.
- Keep all API instances pointed at one shared DB in HA deployments.
When it happens
Trigger: Passing a tenant_id that does not exist (deleted tenant, wrong environment, malformed uuid) to any API that resolves model configuration — chat, embedding, rerank, ASR, TTS setup.
Common situations: Hard-coded tenant ids in scripts after recreating the database; JWT/api-key belonging to a removed user; multi-instance deployments pointing at different DBs.
Related errors
- dataset({id}) not found.
- main() returned a non-JSON-serializable value.
- Repository or path not found. Please check the URL and ensur
- User '{username}' not found
- 404
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/3f300ec967c8f239.
Report an issue: GitHub.