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

  1. Verify the tenant id exists: SELECT id FROM tenant WHERE id = ... or via the user/tenant API.
  2. Obtain tenant_id from the authenticated session/API key rather than hard-coding it.
  3. If the tenant was deleted, recreate the user/tenant or use a valid one.
  4. 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

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


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/3f300ec967c8f239. Report an issue: GitHub.