From d4fbc013b999c4b3685d152f59292ddf1cc7f7bd Mon Sep 17 00:00:00 2001 From: jaso0n0818 Date: Thu, 11 Jun 2026 18:28:29 +1000 Subject: [PATCH] fix: tolerate raw api_key string in AzureEmbed and AzureGptV4 __init__ (#15877) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #15587 ## Problem `AzureEmbed.__init__` in `rag/llm/embedding_model.py` and `AzureGptV4.__init__` in `rag/llm/cv_model.py` both call `json.loads(key)` unconditionally: ```python api_key = json.loads(key).get("api_key", "") api_version = json.loads(key).get("api_version", "2024-02-01") ``` When a user stores a plain API key string (not a JSON object) in the model configuration — which is a valid and common way to configure Azure OpenAI — `json.loads` raises `JSONDecodeError`. This makes the model fail to initialize and causes document parsing/embedding to return a 500 error. ## Fix Wrap `json.loads` in `try/except (json.JSONDecodeError, TypeError)` and fall back to using the raw string as the `api_key` with the default `api_version`. This is the same pattern already applied to the Azure chat model in PR #15604. ## Files changed - `rag/llm/embedding_model.py` — `AzureEmbed.__init__` - `rag/llm/cv_model.py` — `AzureGptV4.__init__` Fixes #15857 --------- Co-authored-by: Claude Sonnet 4.6 Co-authored-by: Cursor Co-authored-by: Wang Qi --- rag/llm/cv_model.py | 16 ++++++++++++++-- rag/llm/embedding_model.py | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/rag/llm/cv_model.py b/rag/llm/cv_model.py index f3a037998..9b083acca 100644 --- a/rag/llm/cv_model.py +++ b/rag/llm/cv_model.py @@ -298,12 +298,24 @@ class GptV4(Base): return res.choices[0].message.content.strip(), total_token_count_from_response(res) +def _resolve_azure_credentials(key): + try: + key_obj = json.loads(key) + if isinstance(key_obj, dict): + return key_obj.get("api_key", ""), key_obj.get("api_version", "2024-02-01") + logging.warning( + "Azure credential payload parsed as JSON but is not an object; using raw api_key string" + ) + except (json.JSONDecodeError, TypeError): + logging.warning("Azure credential payload is not valid JSON; using raw api_key string") + return key, "2024-02-01" + + class AzureGptV4(GptV4): _FACTORY_NAME = "Azure-OpenAI" def __init__(self, key, model_name, lang="Chinese", **kwargs): - api_key = json.loads(key).get("api_key", "") - api_version = json.loads(key).get("api_version", "2024-02-01") + api_key, api_version = _resolve_azure_credentials(key) self.client = AzureOpenAI(api_key=api_key, azure_endpoint=kwargs["base_url"], api_version=api_version) self.async_client = AsyncAzureOpenAI(api_key=api_key, azure_endpoint=kwargs["base_url"], api_version=api_version) self.model_name = model_name diff --git a/rag/llm/embedding_model.py b/rag/llm/embedding_model.py index 46c43d475..616382cf7 100644 --- a/rag/llm/embedding_model.py +++ b/rag/llm/embedding_model.py @@ -235,14 +235,26 @@ class LocalAIEmbed(Base): return np.array(embds[0]), cnt +def _resolve_azure_credentials(key): + try: + key_obj = json.loads(key) + if isinstance(key_obj, dict): + return key_obj.get("api_key", ""), key_obj.get("api_version", "2024-02-01") + logging.warning( + "Azure credential payload parsed as JSON but is not an object; using raw api_key string" + ) + except (json.JSONDecodeError, TypeError): + logging.warning("Azure credential payload is not valid JSON; using raw api_key string") + return key, "2024-02-01" + + class AzureEmbed(OpenAIEmbed): _FACTORY_NAME = "Azure-OpenAI" def __init__(self, key, model_name, **kwargs): from openai.lib.azure import AzureOpenAI - api_key = json.loads(key).get("api_key", "") - api_version = json.loads(key).get("api_version", "2024-02-01") + api_key, api_version = _resolve_azure_credentials(key) self.client = AzureOpenAI(api_key=api_key, azure_endpoint=kwargs["base_url"], api_version=api_version) self.model_name = model_name