{"record":{"id":"482724f6cb83f294","repo":"infiniflow/ragflow","slug":"provider-id-model-obj-provider-id-not-found-for","errorCode":null,"errorMessage":"Provider id={model_obj.provider_id} not found for model {model_name}.","messagePattern":"Provider id=(.+?) not found for model (.+?)\\.","errorType":"exception","errorClass":"LookupError","httpStatus":null,"severity":"error","filePath":"api/db/joint_services/tenant_model_service.py","lineNumber":444,"sourceCode":"        # req now has tenant_llm_id / tenant_embd_id etc. filled in\n    \"\"\"\n    for name_field, (model_type, id_field) in _MODEL_NAME_TO_ID_FIELD_MAP.items():\n        if name_field in params and id_field not in params:\n            try:\n                params[id_field] = resolve_model_id(tenant_id, model_type, params[name_field])\n            except LookupError:\n                logger.debug(\"Could not resolve %s → %s for tenant %s, skipping\", name_field, id_field, tenant_id)\n    return params\n\n\ndef get_api_key(tenant_id: str, model_name: str):\n    # Try direct model ID (UUID) lookup first\n    exist, model_obj = TenantModelService.get_by_id(model_name)\n    if exist:\n        # Verify tenant ownership through the provider chain\n        ok, provider_obj = TenantModelProviderService.get_by_id(model_obj.provider_id)\n        if not ok:\n            raise LookupError(f\"Provider id={model_obj.provider_id} not found for model {model_name}.\")\n        if tenant_id != provider_obj.tenant_id:\n            joined_tenants = TenantService.get_joined_tenants_by_user_id(tenant_id)\n            joined_tenant_ids = [t[\"tenant_id\"] for t in joined_tenants]\n            if provider_obj.tenant_id not in joined_tenant_ids:\n                raise LookupError(f\"Tenant {tenant_id} has no access to provider owned by tenant {provider_obj.tenant_id}.\")\n\n        exist_inst, instance_obj = TenantModelInstanceService.get_by_id(model_obj.instance_id)\n        if not exist_inst:\n            logger.warning(\n                \"Direct-ID resolution: instance not found | tenant_id=%s model_id=%s instance_id=%s\",\n                tenant_id,\n                model_name,\n                model_obj.instance_id,\n            )\n            raise LookupError(f\"Instance {model_obj.instance_id} not found for model {model_name}.\")\n        logger.debug(\n            \"Direct-ID resolution: resolved | tenant_id=%s model_id=%s instance_id=%s\",\n            tenant_id,","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/db/joint_services/tenant_model_service.py#L426-L462","documentation":"LookupError raised by get_api_key during direct model-ID resolution: the tenant_model row exists, but TenantModelProviderService.get_by_id(model_obj.provider_id) failed, meaning the provider row backing this model is gone while the model row still references it. This is referential breakage inside the provider chain, not a caller input problem.","triggerScenarios":"Calling get_api_key(tenant_id, model_id) where tenant_model.provider_id points at a deleted tenant_model_provider row — e.g. provider deletion removed provider/instance rows but left orphan tenant_model rows, or a partial/failed delete.","commonSituations":"Bugs or interrupted provider-deletion flows leaving orphans; direct DB edits; restores where related tables were inconsistent.","solutions":["Delete the orphan tenant_model row (its provider is gone, so it is unusable) or re-add the provider to recreate rows.","Re-select the model on any entity referencing the orphan id.","If reproducible, fix the provider-deletion path to also remove dependent tenant_model rows (delete_models_by_instance_ids / cascade).","Run a consistency check joining tenant_model to tenant_model_provider on provider_id to find other orphans."],"exampleFix":"-- find orphan models\nSELECT m.id, m.provider_id FROM tenant_model m\nLEFT JOIN tenant_model_provider p ON p.id = m.provider_id\nWHERE p.id IS NULL;","handlingStrategy":"try-catch","validationCode":"exist, m = TenantModelService.get_by_id(model_id)\nif exist:\n    ok, _ = TenantModelProviderService.get_by_id(m.provider_id)\n    if not ok:\n        raise ValueError(\"Model references a deleted provider; re-register the model\")","typeGuard":"def model_chain_intact(model_id: str) -> bool:\n    exist, m = TenantModelService.get_by_id(model_id)\n    if not exist:\n        return False\n    ok, _ = TenantModelProviderService.get_by_id(m.provider_id)\n    return ok","tryCatchPattern":"try:\n    key = get_api_key(tenant_id, model_id)\nexcept LookupError as e:\n    if \"Provider id=\" in str(e):\n        # orphaned row: clean up and re-register, never retry as-is\n        ...","preventionTips":["Make provider deletion cascade to its models and instances.","Run periodic LEFT JOIN integrity checks between tenant_model and tenant_model_provider.","Avoid manual DB edits on these tables."],"tags":["referential-integrity","provider","tenant-model","ragflow"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}