Self Checks
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
- Start RAGFlow
v0.26.4 (any deployment).
- Try to add a BaiduYiyan / Qianfan embedding model provider via the admin UI (or
POST /api/v1/llm/factories).
- 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.
- 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:
- Plain string key →
ModelException (the provider REQUIRES a JSON object; no plain-key fallback)
- JSON dict with both fields → return parsed fields
- JSON dict missing
yiyan_ak or yiyan_sk → default to empty string (preserves tolerance)
- JSON list, number, string, null, bool →
ModelException (the new fix)
- Bad JSON string →
ModelException (the new fix)
- Helper propagates the right fields to
BaiduYiyanEmbed.__init__ so the class gets exactly what it needs
A PR fixing this is in progress.
Self Checks
RAGFlow workspace code commit ID
main@ee388b0fa(also reproducible on anyv0.26.xsince the BaiduYiyanEmbed class was introduced).RAGFlow image version
v0.26.4(also reproducible on the current dev image).Other environment information
BaiduYiyan(factory name) — seeconf/llm_factories.jsonandconf/models/baidu.json.BaiduYiyanEmbed(the embedding side of the BaiduYiyan / Qianfan provider) —rag/llm/embedding_model.py:1019-1029c6d1af4b1):BaiduYiyanChat—rag/llm/chat_model.py:1189-1196. PR fix(chat_model): raise clear ModelException when BaiduYiyan key is not a JSON object (closes #17389) #17390 introduced the_resolve_qianfan_credentialshelper inrag/llm/key_utils.pyand wiredBaiduYiyanChat.__init__through it. However, PR fix(chat_model): raise clear ModelException when BaiduYiyan key is not a JSON object (closes #17389) #17390 only fixed the chat side — the embed side has the same shape of bug and was not touched.Actual behavior
The
BaiduYiyanEmbed.__init__method parses its API key as JSON to extract theyiyan_akandyiyan_skfields: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", "")raisesAttributeError: 'list' object has no attribute 'get'key = '"a plain string"'parses to a string → sameAttributeErrorkey = 'null'parses toNone→ sameAttributeErrorkey = '42'parses toint→ sameAttributeErrorkey = 'true'parses tobool→ sameAttributeErrorkey = '3.14'parses tofloat→ sameAttributeErrorIn every case the call site raises an unhandled
AttributeErrorthat 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 insiderag/llminternals — 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 atconf/models/baidu.json.Steps to reproduce
v0.26.4(any deployment).POST /api/v1/llm/factories).["a", "b"]— crashes withAttributeError: 'list' object has no attribute 'get'.42— same crash."a plain string"(with quotes) — same crash.null— same crash.true— same crash.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_credentialshelper inrag/llm/key_utils.pyand wiredBaiduYiyanChat.__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):rag/llm/embedding_model.pyBaiduYiyanEmbedThe fix is a single-line wire-up in
BaiduYiyanEmbed.__init__to use the existing_resolve_qianfan_credentialshelper fromrag/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:
ModelException(the provider REQUIRES a JSON object; no plain-key fallback)yiyan_akoryiyan_sk→ default to empty string (preserves tolerance)ModelException(the new fix)ModelException(the new fix)BaiduYiyanEmbed.__init__so the class gets exactly what it needsA PR fixing this is in progress.