Skip to content

[Bug]: BaiduYiyanEmbed provider crashes with AttributeError when key is a JSON non-object (embed-side companion of #17389; same pattern as #17204 / #17373 / #17456 / #17458 / #17463) #17504

Description

@Harsh23Kashyap

Self Checks

  • I have searched for existing issues, including closed ones.
  • I confirm that I am using English to submit this report.
  • Non-English title submissions will be closed directly.
  • I have not modified the template and have filled in all the required fields.

RAGFlow workspace code commit ID

main @ ee388b0fa (also reproducible on any v0.26.x since the BaiduYiyanEmbed class was introduced).

RAGFlow image version

v0.26.4 (also reproducible on the current dev image).

Other environment information

Actual behavior

The BaiduYiyanEmbed.__init__ method parses its API key as JSON to extract the yiyan_ak and yiyan_sk fields:

# rag/llm/embedding_model.py:1025-1027
key = json.loads(key)
ak = key.get("yiyan_ak", "")
sk = key.get("yiyan_sk", "")

There is no try/except around the json.loads(key) call. A user pasting any input that is NOT a JSON object — for example:

  • key = '[1, 2, 3]' parses to a list → .get("yiyan_ak", "") raises AttributeError: 'list' object has no attribute 'get'
  • key = '"a plain string"' parses to a string → same AttributeError
  • key = 'null' parses to None → same AttributeError
  • key = '42' parses to int → same AttributeError
  • key = 'true' parses to bool → same AttributeError
  • key = '3.14' parses to float → same AttributeError

In every case the call site raises an unhandled AttributeError that bubbles up as a 500 in the API and a stack trace in the server log. This is the same class of bug that PR #17215 fixed for Azure, PR #17377 fixed for Bedrock, PR #17457 fixed for VolcEngine/Ark, PR #17459 fixed for OpenRouter, and PR #17464 fixed for GoogleCV.

The BaiduYiyan / Qianfan provider REQUIRES a JSON object key (per conf/models/baidu.json). A user pasting a plain Baidu API key like "bce-v3/ALTAK-.../..." (the most common mistake: copying from the Qianfan console) OR a JSON non-object (e.g. a JSON list) gets a 500 from inside rag/llm internals — no indication of what they did wrong.

Expected behavior

A user pasting any non-BaiduYiyan-shaped key (a plain API key, a JSON list, a JSON number, a malformed JSON object) should get a clear, actionable error at provider-init time, not a 500. The provider REQUIRES a JSON object, so a non-object input should raise a clear ModelException(retryable=False) with a message that names the required fields (yiyan_ak, yiyan_sk) and points at conf/models/baidu.json.

Steps to reproduce

  1. Start RAGFlow v0.26.4 (any deployment).
  2. Try to add a BaiduYiyan / Qianfan embedding model provider via the admin UI (or POST /api/v1/llm/factories).
  3. Paste any of these into the API key field:
    • A JSON array like ["a", "b"] — crashes with AttributeError: 'list' object has no attribute 'get'.
    • A JSON number like 42 — same crash.
    • A JSON string like "a plain string" (with quotes) — same crash.
    • A JSON null null — same crash.
    • A JSON bool true — same crash.
  4. The server log shows an unhandled AttributeError. The admin UI shows a generic 500 with no actionable hint.

Expected error surface

After the fix, a JSON non-object should raise the same clear error as the chat-side helper (e.g. ModelException(retryable=False) with a message like: "BaiduYiyan key must be a JSON object, got <type>. See conf/models/baidu.json for the model class.").

Coordination note

PR #17390 (commit c6d1af4b1) added a _resolve_qianfan_credentials helper in rag/llm/key_utils.py and wired BaiduYiyanChat.__init__ through it. This fix uses the same helper for the embed side. If PR #17390 lands first, this PR can be rebased to drop the helper re-addition. If this PR lands first, PR #17390 can be rebased to drop its helper addition (just keeping the chat-side wire-up). Either order resolves to the same final state. The maintainers can decide the merge order.

Additional information

Affected files and line numbers (in commit ee388b0fa):

File Class Lines Current state
rag/llm/embedding_model.py BaiduYiyanEmbed 1019-1029 CRASHES on non-JSON or JSON non-object

The fix is a single-line wire-up in BaiduYiyanEmbed.__init__ to use the existing _resolve_qianfan_credentials helper from rag/llm/key_utils.py (the same helper PR #17390 added for the chat side). If the helper is not yet on upstream main when this PR is opened, this PR also re-adds the helper (mirroring PR #17390 verbatim) so the embed site is self-contained.

Regression tests covering:

  1. Plain string key → ModelException (the provider REQUIRES a JSON object; no plain-key fallback)
  2. JSON dict with both fields → return parsed fields
  3. JSON dict missing yiyan_ak or yiyan_sk → default to empty string (preserves tolerance)
  4. JSON list, number, string, null, bool → ModelException (the new fix)
  5. Bad JSON string → ModelException (the new fix)
  6. Helper propagates the right fields to BaiduYiyanEmbed.__init__ so the class gets exactly what it needs

A PR fixing this is in progress.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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