Skip to content

[Bug]: GoogleCV (Google Vertex vision) provider crashes with AttributeError when key is a JSON non-object (same pattern as #17204 / #17373 / #17389 / #17456 / #17458) #17463

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 @ 9b0719fa9 (also reproducible on any v0.26.x).

RAGFlow image version

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

Other environment information

  • Provider: Google factory (covers AnthropicVertex and GeminiVertex via Google Cloud Vertex AI)
  • Affected class: GoogleCV (the CV/vision side of the Google Vertex provider) — rag/llm/cv_model.py:1295-1322
  • Companion class (already actively being worked on by another contributor, NOT in scope for this issue): GoogleChatrag/llm/chat_model.py:1258-1289. Open PR fix(llm): implement async chat methods for GoogleChat (Vertex AI Gemini) #15994 by @glu000 addresses the async chat methods on this class. The JSON-decode bug at chat_model.py:1284 is documented in the issue but the chat side is intentionally left out of this fix to avoid a conflicting PR.
  • Also related: BaiduYiyanEmbed (rag/llm/embedding_model.py:1014) has the same shape and will be filed separately.

Actual behavior

The GoogleCV.__init__ method parses its API key as JSON to extract the Google Cloud service-account fields:

# rag/llm/cv_model.py:1319-1322
key = json.loads(key)
access_token = json.loads(base64.b64decode(key.get("google_service_account_key", "")))
project_id = key.get("google_project_id", "")
region = key.get("google_region", "")

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("google_service_account_key", "") 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 #17390 fixed for BaiduYiyan, PR #17457 fixed for VolcEngine/Ark, and PR #17459 fixed for OpenRouter.

The Google Cloud Vertex AI provider REQUIRES a JSON object key (per the schema in api/apps/llm_app.py:291 and the test in test/testcases/test_web_api/test_llm_app/test_llm_list_unit.py:635-640):

{
  "google_project_id": "<project-id>",
  "google_region": "us-central1",
  "google_service_account_key": "<base64-encoded-service-account-json>"
}

A user pasting a plain string or any other JSON type gets a AttributeError from inside rag/llm internals — no indication of what they did wrong.

Expected behavior

A user pasting any non-Google-Vertex-shaped key (a plain string, 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 (google_project_id, google_region, google_service_account_key) and points at the schema in api/apps/llm_app.py:291.

Steps to reproduce

  1. Start RAGFlow v0.26.4 (any deployment).
  2. Try to add a Google Cloud Vertex model provider (Gemini or Claude via Vertex) for vision use 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 other provider helpers (e.g. ModelException(retryable=False) with a message like: "Google Vertex requires a JSON object with 'google_project_id', 'google_region', and 'google_service_account_key'; got <type>").

Out of scope

  • The chat counterpart GoogleChat at rag/llm/chat_model.py:1284-1289 has the same shape of bug, but PR fix(llm): implement async chat methods for GoogleChat (Vertex AI Gemini) #15994 is open by @glu000 actively working on that class. The chat-side JSON-decode fix should be coordinated with that contributor to avoid conflicting changes — NOT included in this PR.
  • BaiduYiyanEmbed at rag/llm/embedding_model.py:1014 has the same shape and will be filed in a separate issue.

Additional information

Affected files and line numbers (in commit 9b0719fa9):

File Class Lines Current state
rag/llm/cv_model.py GoogleCV 1319-1322 CRASHES on non-JSON or JSON non-object

The fix should be a single helper in rag/llm/key_utils.py (following the established pattern for _resolve_bedrock_credentials, _resolve_qianfan_credentials, _resolve_volcengine_credentials, and _resolve_openrouter_credentials) with regression tests covering:

  1. Plain string key → ModelException (the provider REQUIRES a JSON object; no plain-key fallback)
  2. JSON dict with all fields → return parsed fields
  3. JSON dict missing google_project_id / google_region / google_service_account_key → default to empty strings (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 GoogleCV.__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