Skip to content

[Bug]: Document parsing fails with "Missing credentials" after updating embedding model config — stale tenant_embd_id in task cache #17991

Description

@W0921

Bug Description

After updating an embedding model configuration (api_key / base_url) via the RAGFlow UI, already-queued document parsing tasks fail with:

openai.OpenAIError: Missing credentials. Please pass an `api_key`, `workload_identity`, `admin_api_key`, or set the `OPENAI_API_KEY` or `OPENAI_ADMIN_KEY` environment variable.

The root cause is that the task caches a stale tenant_embd_id pointing to an old tenant_model_instance record whose api_key is empty.

Reproduce

  1. Add an OpenAI-API-Compatible embedding model (e.g. harrier-oss-v1-0.6b) with api_key and base_url
  2. Upload a document and start parsing — task is queued with tenant_embd_id pointing to the current tenant_model_instance record
  3. Update the embedding model config in the UI (change api_key / base_url) — RAGFlow creates a new tenant_model_instance record and updates tenant.tenant_embd_id to point to it; the old record is left behind with api_key=""
  4. The queued task from step 2 executes — it uses the cached old tenant_embd_id, looks up the old tenant_model_instance record, gets api_key="", passes it to OpenAI(api_key=""), and crashes

Expected Behavior

Already-queued tasks should either:

  • Re-resolve the model config from the tenant's current tenant_embd_id at execution time, OR
  • Fall back to the global embd_id when the cached tenant_embd_id yields an empty api_key

Actual Behavior

task_handler.py only falls back when get_model_config_by_id raises LookupError (record not found). But the old record still exists (just with an empty api_key), so no LookupError is raised, and the empty api_key is passed directly to the OpenAI client constructor.

# task_handler.py:355-366
if ctx.tenant_embd_id:
    try:
        embd_model_config = get_model_config_by_id(task_tenant_id, LLMType.EMBEDDING, ctx.tenant_embd_id)
    except LookupError:
        embd_model_config = resolve_model_config(task_tenant_id, LLMType.EMBEDDING, task_embedding_id)

The except LookupError only catches "record not found". An empty api_key is not detected — it flows through to model_instance()EmbeddingModel[...](api_key="", ...)OpenAI(api_key="") → crash.

Environment

  • RAGFlow image: infiniflow/ragflow:latest
  • Version: v0.26.4-831-gf532f27f1 (0d5486a, v0.14.1~75 full)
  • Deployment: Docker Compose (CPU profile)
  • Model: OpenAI-API-Compatible embedding (harrier-oss-v1-0.6b)

Workaround

Manually update the old tenant_model_instance record to set the correct api_key:

UPDATE tenant_model_instance SET api_key='sk-embed' WHERE id='<old_instance_id>';

Suggested Fix

In get_model_config_by_id (or task_handler._bind_embedding_model), add a validation that api_key is non-empty after lookup. If empty, fall back to resolve_model_config or raise a more descriptive error instead of letting an empty string propagate to the OpenAI SDK.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions